链接列表实现内存分配

时间:2014-04-29 11:37:14

标签: c pointers struct linked-list

我使用C中的结构和指针实现了一个链表,如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/* these arrays are just used to give the parameters to 'insert',
 * to create the 'people' array */

#define HOW_MANY 7
char * names[HOW_MANY] = {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim", "Harriet"};
int ages[HOW_MANY] = {22, 24, 106, 6 ,18, 32, 24};

/* declare your struct for a person here */
struct p {
    char *peopleName;
    int age;
    struct p* next;
} person;


struct p* insert_end (struct p *people,char *name, int age) {
    /* put name and age into nthe enxt free place in the array parameter here */
    /* modify nextfreeplace here */
    struct p *nextPerson;

    nextPerson = (struct p*)malloc(sizeof(struct p));

    if (nextPerson == NULL) {
        printf("Error performing malloc.\n");
        return(NULL);
    } else {
        nextPerson -> peopleName = name;
        nextPerson -> age = age;
        if (people == NULL) {
            nextPerson -> next = people;
            return nextPerson;
        } else {
            struct p* temp = people;
            while ((temp -> next) != NULL) {
                temp = temp -> next;
            }
            temp -> next = nextPerson;
            nextPerson -> next = NULL;
            return people;
        }
    }
}



int main (int argc, char **argv) {
    /* declare the people array here */

    struct p *people = NULL;

    for (int i = 0; i < HOW_MANY; i++) {
        people= insert_end(people, names[i], ages[i]);
    }

    while (people != NULL) {
        printf("Freeing\n");
        free(people);
        people = people -> next;
    }


    return 0;
}

这很好用,但我不明白为什么insert_end声明如下时它不起作用:

struct p* insert_end (struct p *people,char *name, int age) {
    /* put name and age into nthe enxt free place in the array parameter here */
    /* modify nextfreeplace here */
    struct p *nextPerson;

    nextPerson = (struct p*)malloc(sizeof(struct p));

    if (nextPerson == NULL) {
        printf("Error performing malloc.\n");
        return(NULL);
    } else {
        nextPerson -> peopleName = name;
        nextPerson -> age = age;
        if (people == NULL) {
            nextPerson -> next = people;
            return nextPerson;
        } else {
            while ((people -> next) != NULL) {
                people= people-> next;
            }
            people-> next = nextPerson;
            nextPerson -> next = NULL;
            return people;
        }
    }
}

如您所见,使用此实现时,内存未正确释放。任何人都可以帮助我理解为什么这不起作用?

2 个答案:

答案 0 :(得分:2)

该函数显然应该返回指向列表中第一个条目的指针。第二个实现没有,而是在列表中已经存在至少一件事的情况下返回指向倒数第二个条目的指针。

答案 1 :(得分:0)

不是你的问题的答案,但即使你使用第一版insert_end工作正常,你在这段代码中有未定义的行为:

while (people != NULL) {
    printf("Freeing\n");
    free(people);
    people = people -> next;  // << you are using people after it has been freed
}

在您的平台上,代码似乎可以正常工作,但这只是偶然的。

这适用于所有平台的所有情况:

while (people != NULL) {
    printf("Freeing\n");

    struct p *temp = people ; 
    people = people -> next;
    free(temp);
}