2016-08-08 6 views
1
char *ptr = (char*)malloc(10); 

    if(NULL == ptr) 
    { 
     printf("\n Malloc failed \n"); 
     return -1; 
    } 
    else if(argc == 1) 
    { 
     printf("\n Usage \n"); 
    } 
    else 
    { 
     memset(ptr, 0, 10); 

     strncpy(ptr, argv[1], 9); 

     while(*ptr != 'z') 
     { 
      ptr++; 
     } 

     if(*ptr == 'z') 
     { 
      printf("\n String contains 'z'\n"); 
      /* Do some more processing */ 
     } 

     free(ptr); 
    } 

In dem vorherigen Code, sagen wir, dass Argumente für das Programm ist: Mixx, gibt das Programm einen Segmentierungsfehler.Größe des zugewiesenen Arbeitsspeichers zu einem Zeiger ändert sich, wenn der Zeiger

Und meine Frage ist:
Wenn ich dies tun in der while-Schleife:

ptr++; 

bedeutet dies, dass die Größe des Speichers auf den Zeiger ptr zugeordnet ändert sich auch, und das ist, warum, wenn ich die freie nennen() Funktion stürzt ab.

+0

Ich sehe dies nicht als eine schlechte Frage. (Gute Beschreibung und Code-Schnipsel). UV'd. – Bathsheba

+0

Sie lesen über das Ende der Zeichenfolge hinaus, da Sie nicht nach dem '\ 0' suchen, während Sie sich in der' while' Schleife befinden. – Koshinae

+0

Es sei denn, 'argv [1]' 'ein 'z'' enthält, ist das Verhalten nicht definiert ist * schon vor dem' free() '*. Folglich kann ein konformer Compiler das 'if (* ptr == 'z')' --check eliminieren, da es nicht falsch sein kann. – EOF

Antwort

4

Ihre Vermutung ist richtig: das Verhalten Ihres Programms ist undefined.

Sie müssen den ursprünglichen Wert von ptr zu free passieren.

(Auch ist while(*ptr != 'z') verwundbar Ihre Eingabe Überholkupplung. Betrachten wir für \0 zu überprüfen.)

+0

Sie meinen, dass ich zählen muss, wie oft ptr in der While-Schleife inkrementiert wurde und dekrementieren Sie danach? –

+0

@ M.Cesar Wäre es nicht unendlich sinnvoller, den Zeiger, der von 'malloc' zurückgegeben wird, in einen' const'-Zeiger zu übernehmen, und dann eine Kopie davon zu nehmen, um später zu inkrementieren? –

+0

Das wäre ein Weg, aber warum nicht den ursprünglichen Wert separat speichern? – Bathsheba

1

Sie nur free einen Zeiger übergeben kann, die von malloc, calloc oder realloc zurückgegeben wurde. Was Sie passiert haben, war ein anderer Zeiger. Die Tatsache, dass es innerhalb des zugewiesenen Blocks zeigt, spielt keine Rolle.

Sie müssen den ursprünglichen Zeiger verfolgen, damit er freigegeben werden kann.

Wenn Sie die Zeichenfolge durchlaufen, überprüfen Sie nicht, ob Sie das Ende der Zeichenfolge erreicht haben. Wenn Sie nach dem Nullabschluss suchen, greifen Sie auf Speicher zu, den Sie nicht besitzen, und rufen Sie nicht definiertes Verhalten auf.

das Kontroll hinzufügen wie folgt:

while(*ptr != 'z' && *ptr != '\0') 
+0

Dies scheint rückwärts. Um Unfälle zu vermeiden, akzeptieren Sie das Original mit einem '* const', und kopieren Sie _that in eine Nicht-'const' für die Zeigerarithmetik. –

Verwandte Themen