#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;
}
每次运行上面的函数时,都会出现一些错误内存。我已经考虑了几个小时,但不知道这个有什么问题。
答案 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);
}