Speicherfehler? Komischer Effekt beim Einlesen von Daten



  • Hallo!

    Aktuell stehe ich ganz schön auf dem Schlauch, weil ich den Effekt nicht verstehe...

    Ich habe eine eigene globale Variable definiert:

    typedef struct{
      int ID;
      double Emod;
      double Gmod;
      double Nue;
      double Rho;
      char Label[201];
      char Regex_Label[201];
      } Type_ValidNVHMaterial;
    
    Type_ValidNVHMaterial* ValidNVHMaterial;
    int AnzValidNVHMaterial=0;
    

    In der Funktion ReadIni wird eine Initialisierungsdatei gelesen, mit der dieses struct befüllt werden soll (Speicher dafür ist reichlich alloziert worden):

    if (strncmp(Line,"NVH_MAT",strlen("NVH_MAT")) ==0){
        Num=0;
          if (Debug) printf("\n'%s'\n",Line);
          Token = strtok(Line," \n");
          while (Token){
            if (Debug)printf("Token[%i]: %s\n",Num,Token);
            if (Num==1)ValidNVHMaterial[AnzValidNVHMaterial].ID   = atoi(Token);
            if (Num==2)ValidNVHMaterial[AnzValidNVHMaterial].Emod = atof(Token);
            if (Num==3)ValidNVHMaterial[AnzValidNVHMaterial].Gmod = atof(Token);
            if (Num==4)ValidNVHMaterial[AnzValidNVHMaterial].Nue  = atof(Token);
            if (Num==5)ValidNVHMaterial[AnzValidNVHMaterial].Rho  = atof(Token);
            if (Num==6)strncpy(ValidNVHMaterial[AnzValidNVHMaterial].Label,Token,strlen(Token));
            if (Num==7)strncpy(ValidNVHMaterial[AnzValidNVHMaterial].Regex_Label,Token,strlen(Token)-1);
            Num++;
            Token = strtok(NULL," ");
          }//while(Token)
          if (Debug) printf("AnzValidNVHMaterial %i",AnzValidNVHMaterial);
          AnzValidNVHMaterial++;
        }
    

    Der direkte debugoutput gem. obigem code sieht gut aus:

    Token[0]: NVH_MAT
    Token[1]: 1
    Token[2]: 210000.0
    Token[3]: 0.0
    Token[4]: 0.3
    Token[5]: 7.85e-9
    Token[6]: Stahl
    Token[7]: ^STAHLStahl|^Stahl

    Wenn ich aber direkt danach mit zu Kontrollzwecken den Inhalt des structs ausgeben lasse, habe ich seltsame Zeichen in den Labeln:

    for (i=0;i<AnzValidNVHMaterial;i++){
         printf("No...: %i\n",  i                              );
         printf("ID...: %i\n",  ValidNVHMaterial[i].ID         );
         printf("EMOD.: %#g\n", ValidNVHMaterial[i].Emod       );
         printf("GMOD.: %#g\n", ValidNVHMaterial[i].Gmod       );
         printf("NUE..: %#g\n", ValidNVHMaterial[i].Nue        );
         printf("RHO..: %#g\n", ValidNVHMaterial[i].Rho        );
         printf("LABEL: '%s'\n",ValidNVHMaterial[i].Label      );
         printf("REGEX: '%s'\n",ValidNVHMaterial[i].Regex_Label);
         printf("\n");
       }
    

    ID...: 1
    EMOD.: 210000.
    GMOD.: 0.00000
    NUE..: 0.300000
    RHO..: 7.85000e-09
    LABEL: 'Stahl©þ
    ¤©
    °©
    ¼©
    '
    REGEX: '^STAHLStahl|^Stahl'

    Das sieht nach einem Speicherfehler aus, allerdings kann ich mir den nicht erklären. Der struct hat Platz für 1000 Einträge, gelesen werden in Summe 9.
    Die Länge der einzelenen char ist mit 201 auch deutlich größer als benötigt.
    Die Token, die ich auslese sind korrekt, es sind keine versteckten CTRL-Zeichen o.ä. in der ini-Datei.

    Nun weiß ich nicht mehr weiter... Hat jemand noch eine Idee?

    Ciao

    OkkaPapa



  • Du musst Strings in C nullterminieren, d.h. das letzte Element im char-Array muss '\0' sein.

    Hast du das vielleicht in nachfolgendem Code gemacht? printf und andere Funktionen nutzen diesen Nullterminator, um das Ende des Strings zu erkennen. Wenn kein Nullterminator da ist, dann gibt printf einfach weiter Zeichen aus, eben die Zeichen, die in den String nachfolgenden Speicherzellen sind.



  • ⚠ strncpy schreibt keine '\0' an das Ende, wenn die Anzahl der zu kopierenden Zeichen erreicht ist.



  • strings nullterminiert?
    Sonst gibt printf nämlich alles aus, bis es zufällig im Speicher eine 0 findet.



  • Da gehört auch nicht strlen(Token) hin sondern die 201.
    Sonst kannst du auch gleich strcpy nehmen.



  • Hallo!

    das mit der Nullterminierung läßt meinen code an anderer Stelle abstürzen... aber immerhin komme ich korrekt übers Einlesen weg.

    strncpy habe ich gemacht, weil ich vermeiden will, daß der Zeilenumbruch mitgelesen wird.

    Das hat sonst nachher in der Gui unschöne Effekte und ich weiß nicht wie regex.h auf Zeilenumbrüche im regulären Ausdruck reagiert.

    Ciao

    OkkaPapa



  • Am besten, du überschreibst die '\n' (Zeilenumbrüche) einfach mit '\0' .



  • Warum hast du denn den '\n' nicht mit bei strtok?



  • DirkB schrieb:

    Warum hast du denn den '\n' nicht mit bei strtok?

    ich dachte ich hätte:

    Token = strtok(Line," \n");
    


  • Für jeden Token kannst du neue Trennzeichen definieren.
    Und bei strtok(NULL, fehlt der '\n'.


Anmelden zum Antworten