2016-08-08 9 views
-3

Ich habe eine while Schleife innerhalb einer for Schleife, um Strings zu behandeln. Hier ist im Grunde die Struktur meines Code:Probleme mit free() Funktion in C

char myString[1000]; 
//Initialize and maybe change myString 
for(/*conditions*/){ 
    while(/*conditions*/){ 
     if(strchr(myString,' ') == NULL){ 
      break; 
     } 
     char *temp = malloc(sizeof(char) * strlen(myString)); 
     strcpy(temp,myString); 
     *strchr(temp,' ') = '\0'; 
     strcat(myString," "); 
     strcat(myString,temp); 
     free(temp); 
    } 
} 

Manchmal dieser Code funktioniert gut, aber manchmal endet der Prozess und gibt 3, was bedeutet, dass es einen Fehler (3 wird der Rückgabewert, dass ich in der Regel erhalten, wenn Ich versuche, NULL zu verwenden, wo ich nicht wie zum Beispiel myPointer->example wo myPointer ist NULL) mögen sollte. Nach einigen Tests fand ich heraus, dass die Linie, die das Problem verursachte, free(temp); ist. Ich habe versucht, es durch if(temp != NULL){free(temp);} zu ersetzen, aber es änderte nichts. Ich habe versucht, temp mit char temp[1000] anstelle von malloc zu deklarieren und die free(temp); Linie wegzunehmen, aber es tut immer noch das Gleiche. Wenn ich die free(temp); Zeile wegnehme und immer noch malloc benutze, ist das Problem gelöst, aber stattdessen gibt es ein riesiges Speicherleck, also kann ich das nicht tun. Wenn es einen Fehler gibt oder nicht, hängt davon ab, was in der myString Zeichenfolge ist, was bedeutet, dass, wenn dort ein bestimmter Wert ist, immer ein Fehler auftritt, und wenn es einen anderen bestimmten Wert gibt, gibt es nie einen Fehler, aber ich kann nicht herausfinden, welche Art von Werten funktionieren und welche nicht, es scheint zufällig zu sein.

Warum funktioniert free(temp); manchmal und manchmal nicht und wie kann ich es immer funktionieren?

+5

'char * temp = malloc (sizeof (char) * strlen (myString)); strcpy (temp, myString); Out-of-Bounds schreiben, undefiniertes Verhalten. Undefiniertes Verhalten für 'NULL'-Dereferenz, wenn' strchr() '' NULL' zurückgibt. – EOF

+0

Außerdem ist 'sizeof (char)' eine Definition, daher ist es redundant als Teil des an 'malloc() 'übergebenen Arguments. –

+0

Ich stimme für die Schließung dieser Frage, weil das Problem durch einen einfachen Tippfehler verursacht wurde. –

Antwort

5

Das Hauptproblem ist, dass Sie ein Element weniger als den erforderlichen Speicher zuweisen.

strlen() berücksichtigt nicht die abschließende Null, so dass Sie den erforderlichen Arbeitsspeicher knapp unterschreiten. Später ist

strcpy(temp,myString); 

tatsächlich tun, aus dem gebundenen Zugang (speichern die abschließende Null), die undefined behavior aufruft. Als Ergebnis erhalten Sie

Manchmal zu sehen, dieser Code funktioniert gut, aber manchmal endet der Prozess und gibt 3, was bedeutet, dass es ein Fehler ist [....]

zu beheben, sollten Sie die Zuweisung Aussage wie

char *temp = malloc(strlen(myString) + 1); // +1 for terminating null, 
              // sizeof(char) == 1, guaranteed by C standard. 

modifizieren das heißt, von der man page

Die strchr() und strrchr() Funktionen geben einen Zeiger auf den gefundenen Zeichen oder NULL, wenn das Zeichen nicht gefunden wird. [...]

und, für das Szenario hervorgehoben,

*strchr(temp,' ') = '\0';

Versuche zu dereferenzieren einem Null-Zeiger-Konstante (NULL), die ist ungültig und ruft UB erneut auf.Suchen Sie nach einem gültigen Rückgabewert, bevor Sie den zurückgegebenen Zeiger zurücksetzen

+0

.... und im Falle von UB kann ein erwartetes oder unerwartetes Ergebnis auftreten. – haccks

+0

@hacks Richtig, Herr, habe gerade den Teil aus der Frage zitiert, um dies relevant zu machen. :) –

+0

@DonaldDuck überprüfen Sie die Bearbeitung in der Antwort, wenn das Problem bestehen bleibt, erstellen Sie bitte ein MCVE. –