C Speicher in Funktion reservieren?!

Janiiix3

Aktives Mitglied
28. Sep. 2013
1.333
10
38
Hannover
Sprachen
  1. ANSI C
  2. C#
Hallo liebe Gemeinde,

Meine Frage heute lautet: Ist das überhaupt so ohne weiteres auf einem Mikrocontroller möglich, diese Funktion zu nutzen?

Konkret.: Ich habe eine Funktion geschrieben, welche mir ein Kommando aus einem String sucht. Ganz egal was davor steht oder was danach kommt. Dieser Funktion übergebe ich als ersten Parameter den Speicher in dem er den String suchen soll, als zweiten Parameter übergebe ich den such String. Der kann z.B so aussehen "LED:ON", er kann aber auch so aussehen "LED:xx". Mit den xx untersuche ich den String und speichere einfach die Positionen wo die "x" ab und untersuche später was an dieser Stelle für Informationen lauern.

Das funktioniert auch alles. Manchmal habe ich nur das Problem, dass das Programm komplett einen Sittich macht. Das tut es aber auch nur wenn ich mit der Funktion "malloc()" Speicher reservieren möchte (in der Funktion)
Reserviere ich den Speicher statisch, klappt es wie es soll.. Sprich "char *buff = "xxxxxxxxxxxxxxx"// Platz für 15 Bytes..

Gehe ich falsch mit der Funktion "malloc()" um?



CodeBox C
int8_t srchCmd(char *inBuff, char *srchCmd)
{
     char *cmdBeginn        = NULL;
     char *cmdEnd             = NULL;
     char *rawData           = NULL;
    uint8_t cmdStrLen       = strlen(srchCmd);
    uint8_t rawData_       = 0;

   if (inBuff == NULL || srchCmd == NULL)
   return -1;

   /*
   *   how much raw data we will received?
   */
   rawData = strchr(srchCmd,'x');
   if(rawData != NULL)
   while(*rawData++ == 'x')rawData_++;
         
   /*
   *    search first character from our string without nx
   */
   //char *cmdBeginn_ = malloc(sizeof(char)*cmdStrLen);
   char *cmdBeginn_ = "XXXXXXXXXXXXXXXXXXXX";
   if (cmdBeginn_ != NULL)
   strcpy(cmdBeginn_,srchCmd);
   else
   return -1;
     
   /*
   *   mask the nx out
   */  
   if (rawData_ > 0)
   {
       cmdBeginn_ += (cmdStrLen-rawData_);
       *cmdBeginn_ = '\0';
       cmdBeginn_ -= (cmdStrLen-rawData_);       
   }
       
   cmdBeginn = strstr(inBuff,cmdBeginn_);
   if(cmdBeginn == NULL)
   return -1;
     
   /*
   *    search last character from our string
   */     
   cmdEnd = strrchr(cmdBeginn,cmdBeginn_[cmdStrLen-rawData_]);
   if(cmdEnd == NULL)
   return -2;

   /*
   *    terminate end of searched string
   */
   cmdBeginn+=cmdStrLen;
   *cmdBeginn = '\0';
   cmdBeginn-=cmdStrLen;

   /*
   *    copy the command to buffer
   */
   strcpy(inBuff,cmdBeginn);
   
   return 0;
}

 
Prinzipiell möglich ist es durchaus, die Funktion malloc auf einem µC zu nutzen, ob es sinnvoll ist, ist eine andere Frage.

Grundsätzlich darfst Du den von malloc zurückgegebenen Zeiger niemals verändern, den brauchst Du nämlich um den Speicherbereich am Ende der Funktion mit free wieder freizugeben, sonst geht Dir schnell der Speicher aus...

Mit


CodeBox C
char *cmdBeginn_ = "XXXXXXXXXXXXXXXXXXXX";
innerhalb der Funktion reservierst Du den Speicher nicht statisch, sondern dynamisch (auf dem Stack), er wird am Ende der Funktion automatisch freigegeben.
 
Wenn ich ihn mit der Anzahl von "x" initalisiere? Ist das nicht wie bei einem Array? char buff[]= "12345";
Da hat das Array jetzt die Größe von "5"?
 
Da Du nicht das Schlüsselwort "static" verwendest, wird das Array jedesmal bei Aufruf der Funktion auf dem Stack angelegt und initialisert, ob nun mit "xxx..." oder "123..."
Mit "static" (oder als globale Variable, außerhalb aller Funktionen) wird das Array irgendwo im Speicher dauerhaft angelegt und nur einmal initialisert.
 
Okay. Dann sollte ich das schleunigst mit static versehen.
Und was ist mit "malloc"? Was mache ich da falsch? Das es ab und zu mal abstürzt?
 
Dann sollte ich das schleunigst mit static versehen.
Das ist nicht nötig ;) Du solltest lieber die Kapitel 5 Zeiger und Vektoren und 6 Strukturen im Kernighan/Ritchie gründlich durcharbeiten. ;)
Und wie ich oben schon schrieb: malloc() benutzt man niemals ohne free() ...
 
Wenn er es auf dem Stack ablegt ist es dann nicht langsamer als im RAM?


Kernighan/Ritchie ist das ein Buch?
 


CodeBox C
char *cmdBeginn_ = "XXXXXXXXXXXXXXXXXXXX";
[/C
Es ist doch aber richtig, das für die Anzahl von den 'x' Speicherplatz freigehalten wird oder?


Es gibt div. Bücher. Hast du einen link?
 
Zuletzt bearbeitet:
Ob Du schreibst:


CodeBox C
char *cmdBeginn_ = "XXXXXXXXXXXXXXXXXXXX";
oder


CodeBox C
char cmdArray[] = "XXXXXXXXXXXXXXXXXXXX";

spielt keine Rolle. Der Compiler reserviert dafür 20 Bytes auf dem Stack und kopiert den String "XXXXXXXXXXXXXXXXXXXX" aus dem Flash da rein.

Das Buch ist ja immer noch so teuer. Für meine erste englische Version habe ich auch schon über 70 DM bezahlt. https://www.buecher.de/shop/program...m-/products_products/detail/prod_id/03761667/
 
Das scheint viel ausführlicher zu sein, ob es auch besser ist kann ich nicht sagen.
In den Kapiteln 11,12,14 und 15 sollte in etwa das stehen, was ich oben angesprochen habe.
 
Wenn ich diese Funktion genau so mit DevC++ (also als C Projekt) starte, stürzt es ab.
Wenn ich es jedoch in der Funktion mit "malloc()" mache, klappt es?!
Auf nem µC funktioniert "malloc()" nicht.. Woran liegt das?
 
Gibt es denn ein Problem, wenn ich es so in der Funktion, zur Laufzeit reserviere?


CodeBox C
/*

* internal command buffer
*/
char cmdBeginn_[[I]strlen[/I](srchCmd)]; 

[I]strcpy[/I](cmdBeginn_,srchCmd);
 
Gibt es denn ein Problem
strlen liefert die Anzahl der Zeichen, ohne Abschlusszeichen, zur Laufzeit. Kurz: cmdBegin_ ist zu klein und ein Array wird nicht dynamisch zur Laufzeit erstellt, sondern beim kompilieren.
 
Also zur Laufzeit erwarte ich max. 25 Zeichen.
Jedoch nicht immer. Würde es Sinn machen, direkt einen Buffer für 25 Zeichen zu reservieren? Oder dies lieber „dynamisch“ gestalten?

Wenn ich es „dynamisch“ mache, würde es so klappen?

char *buffer = malloc(sizeof(char)*strlen(srchCmd));

if(buffer==NULL)

{

return "es konnte kein Speicher reserviert werden.";

}



/*

+ buffer manipulieren..

*/

free(buffer);
 
Also zur Laufzeit erwarte ich max. 25 Zeichen.
Jedoch nicht immer. Würde es Sinn machen, direkt einen Buffer für 25 Zeichen zu reservieren? Oder dies lieber „dynamisch“ gestalten?

Ich würde den Buffer einfach fest mit 26 Array-Elementen erstellen.

char buffer[26];

Da du mit Strings arbeitest, ein Element mehr als Zeichen für den Stringabschluss.
 
Ja okay. Wie sieht es denn nun mit "malloc()" aus? Ist meine Herangehensweise falsch?
Ich alloziere Speicher, frage ab ob es geklappt hat, beschreibe den frei gegebenen Speicher und gebe ihn beim verlassen der Schleife wieder frei.
 
Ich würde sagen, es ist so richtig.

Der buffer ist allerdings um ein Byte zu klein und kann das String-Ende-Zeichen nicht aufnehmen. strlen gibt die Stringlänge ohne das Abschlusszeichen zurück.
 
Okay, nur wieso stürzt die App dann ab und zu mal ab? Wenn ich das mit dem Array mache, ist alles wunderbar.
Da habe ich bis jetzt noch keine Abstürze gehabt.

Wie ist das eigentlich mit "malloc", ist das für die CPU deutlich aufwendiger?
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)