2010-12-15 9 views
1

ich den folgenden Code-Snippet haben:C Malloc Laufzeitfehler

typedef struct person { 
    char *first ; 
    char *last ; 
    char *location ; 
    struct person *next_person ; 
} person ; 

person *make_person(char *first, char *last, char *location) { 
    person *personp = (person*) malloc(sizeof(struct person)); 

    personp->first = (char*) malloc(sizeof(strlen(first) + 1)); 
    personp->last = (char*) malloc(sizeof(strlen(last) + 1)); 
    personp->location = (char*) malloc(sizeof(strlen(location) + 1)); 

    strcpy(personp->first, first); 
    strcpy(personp->last, last); 
    strcpy(personp->location, location); 

    personp->next_person = NULL; 

    return personp ; 
} 

Wenn ich es mit dem Rest meines Codes integrieren, es beginnt mit der Ausführung schreitet dann ausrasten.

*** glibc detected *** ./level1: free(): invalid next size (fast): 0x0804a188 *** 

Irgendeine Idee, was schief läuft? Ich habe das Gefühl, dass es mit meinem Malloc zu tun hat.

+4

Stil: Warum werfen Sie den zurückgegebenen Zeiger explizit aus 'malloc'? In C ist das nicht nötig und kann sogar Probleme verstecken. Und was ist ein 'Lied'? Wo "frei" Sie Ihre Hinweise? – birryree

+0

Neugierig: Warum versteckt es Probleme? Und tut mir leid wegen dem "Lied". Ich habe das Problem modifiziert und das verpasst. Ich entschuldige mich. – Mike

+0

vergessen Sie nicht zu überprüfen, malloc erfolgreich zugeordnet – dubnde

Antwort

11

Sie tun:

personp->first = (char*) malloc(sizeof(strlen(first) + 1)); 

, die nicht korrekt ist. Sie sollten sizeof nicht so verwenden, wie Sie es gewohnt sind. Sie benötigen:

personp->first = malloc(strlen(first) + 1); 
+0

Oh guter Fang, ich beschönige das. Es scheint, als hätte er wirklich Glück gehabt, dass das nicht in 'make_person' explodiert ist, da es scheint, als würde er nur Probleme während' free' bekommen. Sie müssen jedoch keinen expliziten Pointer-Cast von 'void *' durchführen, der von 'malloc' in C zurückgegeben wird. ;) – birryree

+0

@birrreee: Danke, dass du mich an die Besetzung erinnert hast. – codaddict

+2

+1 zum Entfernen des schädlichen Gusses –

2

Warum machst du eine Person in ein Lied?

person *personp = (song*) malloc(sizeof(struct person)); 
0

cast person

person *personp = (person *) malloc(sizeof(struct person)); 

nicht sizeof

personp->first = (char*) malloc(strlen(first) + 1); 
personp->last = (char*) malloc(strlen(last) + 1); 
personp->location = (char*) malloc(strlen(location) + 1); 

Sie auch erfolgreich malloc war

1

überprüfen müssen tun Und btw gibt es eine Funktion zu mach was du willst, es ist strdup es ist nicht in der C-Norm ist aber fast überall, und kann schließlich in einem 2-Liner umgesetzt werden, wenn es nicht ist.

person *make_person(const char *first, const char *last, const char *location) { 
    person *personp = malloc(sizeof(struct person)); 

    personp->first  = strdup(first); 
    personp->last  = strdup(last); 
    personp->location = strdup(location); 
    personp->next_person = NULL; 

    return personp ; 
} 

EDIT: Ich habe auch const-Qualifikation auf die Signatur der Funktion, wie die Saiten übergeben werden nur gelesen und nicht geändert. Dies gibt dem Programmierer, der diese Funktion in der Zukunft verwenden wird, ein wenig mehr Informationen. Er wird wissen, dass er seine Puffer und konstanten Saiten sicher passieren kann, ohne sich Sorgen zu machen, dass die Funktion explodieren könnte.