Ich weiß, dass dies eine Frage ist, die ziemlich häufig gestellt wurde, aber ich habe mehr als 10 geschlossene Fragen ohne Glück gelesen, da meine Lösung mit den von anderen vorgeschlagenen Lösungen übereinstimmt .Fehler beim Freigeben eines 2D-Arrays von Malloc'd-Strings in C
Ich schreibe meine eigene Shell als eine Lernübung und dabei malloc'ing eine Reihe von Strings, die als Argumente eines Programmaufrufs dienen. Mein malloc wird wie folgt durchgeführt, wo argcnt die Anzahl der Argumente ist gegeben + 2 den Standard argv Format anzupassen und das Array ermöglichen null beendet und damit von execvp verwendet werden:
char ** args;
args = (char **) malloc(argcnt*sizeof(char *));
for(i = 0; i < argcnt; i++) {
args[i] = (char *) malloc(80*sizeof(char));
printf("Made %d\n", i);
}
Ich befreie dann den gleichen Speicher wie follows:
for (i = 0; i < argcnt; i++) {
free(args[i]);
printf("Freed %d\n", i);
}
free(args);
Das Programm kompiliert, schlägt aber bei der Freigabe von argv [1] zur Laufzeit fehl. Die Beispielausgabe das Programm ausgeführt wird und dann ls -a -l
Aufruf lautet wie folgt:
[email protected]:~/myshell$ ./myshell
[30/03 23:34] # ls -a -l
Argcnt: 4
Made 0
Made 1
Made 2
Made 3
Arg[0]: ls
Arg[1]: -a
Arg[2]: -l
Arg[3]: (null)
Freed 0
*** Error in `./myshell': free(): invalid pointer: 0x0000000001a84c43 ***
Aborted (core dumped)
ich damit für die letzten 2 Stunden Ringen haben und können nicht herausfinden, was falsch ist, so einen Einblick in das Problem wäre sehr geschätzt.
EDIT: Die Funktion zur Zeit meines Programm zu brechen ist:
void breakargs(char * cmd, char ** args) {
char * tok = malloc(strlen(cmd)*sizeof(char)); //maximum token size is full cmd
char * str = malloc(strlen(cmd)*sizeof(char));
int i=1;
strcpy(str, cmd); //maintains integrity of cmd
args[0] = tok = strtok(str, " ");
while (tok != NULL)
{
args[i] = tok = strtok(NULL, " ");
i++;
}
args[i] = '\0';
free(tok);
}
2. EDIT: Das Problem war meine Neuzuweisung der von meiner ursprünglichen malloc mit strtok gemacht Zeiger so, dass der ursprüngliche Zeigerverweis verloren. Darüber hinaus könnte meine Verwendung einer bestimmten Stringlänge für Argumente möglicherweise zu Problemen führen. Die Lösung bestand darin, nur malloc args [i] zu verwenden, als ich die Länge der Zeichenfolge kannte, die dort gespeichert werden musste, und die Zeichenfolge dann mit strcpy an die Speicherstelle zu verschieben, anstatt sie direkt zuzuweisen. Dies bewahrt die Integrität der Zeigerreferenz und ermöglicht, dass sie korrekt freigegeben wird.
Versuchen Sie * nur * Zuweisen und dann Freigeben, mit nichts dazwischen. Ist das erfolgreich? –
Etwas wie 'char **' ist ** nicht ** ein 2D-Array und kann keines darstellen. Ein Array ist ein fortlaufender Speicherblock von Elementen desselben Typs mit einem linearen Adressierungsschema. Bei einem 2D-Array ist jedes Element selbst ein Array. Sie haben einen "Zeiger auf Zeiger". Wenn Sie ein 2D-Array möchten, verwenden Sie eins.Eine typische Deklaration wäre 'char (* arr) [INNER_LENGTH];' notiere die Klammern! Nur dieses kann mit einem einzigen "malloc"/"free" zugewiesen und freigegeben werden. – Olaf
[Nicht das Ergebnis von malloc in C werfen] (http://stackoverflow.com/q/605845/3959454) –