如何为指针分配内存

时间:2014-11-15 09:09:20

标签: c pointers struct

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

struct date {
    int year;
    int month;
    int day;
};

struct person{
    char name[64];
    struct date birthday;
};

struct aop {
   int max;
   struct person **data;
};

 struct aop *create_aop(int max) {
    struct aop *new = malloc(sizeof(struct aop));
    new->data = malloc(max*sizeof(struct person));
    for (int i=0; i<max; i++) {
    new->data[i] = NULL;
    }
    new->max = max;
    return new;}

void destroy_aop(struct aop *a) {
    free(a->data);
    free(a);
}


int add_person(struct aop *a, char *name, struct date birthday) {
    if (a->data[a->max-1] != NULL) {
        return -1;
    }
    struct person *new_person = malloc(sizeof(struct person));
    strcpy(new_person->name, name);
    new_person->birthday = birthday;
    for (int i=0; i<a->max; i++) {
        if (a->data[i] == NULL) {
            a->data[i] = new_person;
            break;
        }
    }
    free(new_person);
    return 0;
}    

我对我写的代码有一些疑问。首先,我是否需要在create_aop中添加额外的代码来初始化人的名字和生日?我发现在add_person中的free(new_person)之后,我无法访问a-&gt; data [0] - &gt; name。如何在不使用其他指针的情况下更改a-&gt; data [i]?

struct aop *birthdays(const struct aop *a, int month) {
    int m = a->max;
    struct aop *n = create_aop(m);
    int j = 0;
    for (int i=0; i<m; i++) {
        if (a->data[i] != NULL) {
            if (a->data[i]->birthday.month == month) {
                n->data[j] = a->data[i];
                j++;
            }
        } else {
            break;
        }
    }
    if (j == 0) {
        return NULL;
    }
    return n;
}

每次运行上面的函数时,都会出现一些错误内存。我已经考虑了几个小时,但不知道这个有什么问题。

1 个答案:

答案 0 :(得分:1)

此代码中存在两个重大错误。首先,在struct aop中分配数据数组是有缺陷的。

new->data = malloc(max*sizeof(struct person));

你不希望它指向一个人体结构长度最大倍数的记忆,对吗?因为它是指向指针的指针,所以它的大小只需要是指针的最大长度,即

new->data = malloc(max*sizeof(struct person*));

您也可以让数据直接指向struct person。然后第一行是正确的,每次创建新人时都不必分配内存。相反,您只需使用数据指向的内存:

(aop->data[i]).name = ...

等等。

其次,您在创建后立即释放您的人员结构。

free(new_person);

现在aop-&gt; data [i]是一个悬空指针,因为它指向的地址可能随时被覆盖(因为它不再被malloc锁定)。相反,你必须在你的销毁功能中释放它。它可能看起来像这样:

void destroy_aop(struct aop *a) {    
  int i;
  for(i = 0; i < a->max; i++)
    {
      if(a->data[i] != NULL) {
      free(a->data[i]);
      }
    }
    free(a->data);
    free(a);
}
相关问题