Willkommen in unserer Community

Werde Teil unserer Community und registriere dich jetzt kostenlos ...

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

C Speicher in Funktion reservieren?!

Dieses Thema im Forum "Software" wurde erstellt von Janiiix3, 11. Dezember 2017.

  1. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    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 und 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;
    }
    
    
     
  2. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    110
    Zustimmungen:
    9
    Ort:
    Großraum Hannover
    Sprachen:
    C, Assembler
    Map
    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
    innerhalb der Funktion reservierst Du den Speicher nicht statisch, sondern dynamisch (auf dem Stack), er wird am Ende der Funktion automatisch freigegeben.
     
  3. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    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"?
     
  4. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    110
    Zustimmungen:
    9
    Ort:
    Großraum Hannover
    Sprachen:
    C, Assembler
    Map
    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.
     
  5. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    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?
     
  6. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    110
    Zustimmungen:
    9
    Ort:
    Großraum Hannover
    Sprachen:
    C, Assembler
    Map
    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() ...
     
  7. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Wenn er es auf dem Stack ablegt ist es dann nicht langsamer als im RAM?


    Kernighan/Ritchie ist das ein Buch?
     
  8. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    110
    Zustimmungen:
    9
    Ort:
    Großraum Hannover
    Sprachen:
    C, Assembler
    Map
    Der Stack ist im RAM ;)

    Kernighan/Ritchie ist DAS C-Buch.
     
  9. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map


    CodeBox C und 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?
     
    #9 Janiiix3, 11. Dezember 2017
    Zuletzt bearbeitet: 11. Dezember 2017
  10. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    110
    Zustimmungen:
    9
    Ort:
    Großraum Hannover
    Sprachen:
    C, Assembler
    Map
    Ob Du schreibst:
    oder


    CodeBox C und 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/
     
  11. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
  12. Mikro23

    Mikro23 Mitglied

    Registriert seit:
    2. Januar 2017
    Beiträge:
    110
    Zustimmungen:
    9
    Ort:
    Großraum Hannover
    Sprachen:
    C, Assembler
    Map
    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.
     
  13. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    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?
     
  14. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    Gibt es denn ein Problem, wenn ich es so in der Funktion, zur Laufzeit reserviere?


    CodeBox C und C++
    /*
    
    * internal command buffer
    */
    char cmdBeginn_[[I]strlen[/I](srchCmd)]; 
    
    [I]strcpy[/I](cmdBeginn_,srchCmd);
    
     
  15. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.103
    Zustimmungen:
    107
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    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.
     
  16. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    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);
     
  17. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.103
    Zustimmungen:
    107
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    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.
     
  18. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    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.
     
  19. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.103
    Zustimmungen:
    107
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    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.
     
  20. Janiiix3

    Janiiix3 Aktives Mitglied

    Registriert seit:
    28. September 2013
    Beiträge:
    1.050
    Zustimmungen:
    6
    Ort:
    Hannover
    Sprachen:
    C
    Map
    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?
     

Diese Seite empfehlen

  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)