我正在学习C而且我无法释放动态分配的结构数组。 这是我的示例代码:
typedef char Str50[50];
typedef struct exam {
Str50 firstname;
Str50 lastname;
Str50 className;
int score;
Str50 date;
} Exam;
Exam *examDB
size_t allocateAndFreeTheStructArray {
size_t numRecs = 100; //let's say the array contains 100 elements
examDB = malloc(numRecs * sizeof * examDB); //this allocates the needed memory
// the code below tries to free what malloc allocated
for (size_t i = 0; i < numRecs; i++) {
free(&examDB[i]);
}
free(examDB);
}
当我为windows编译它时,一切正常(似乎)。当我使用xcode在我的mac上编译同一段代码时,我收到一条错误消息: “malloc:***对象0x7fae610060d0错误:未释放指针被释放”
怎么可能?我使用malloc来创建数组......我在这里缺少什么?
答案 0 :(得分:2)
每个free
都需要malloc
。你有多少malloc
个? 1,你需要多少free
?只是1。
您正在分配一个100 * sizeof(examDB)
元素数组,这些元素是动态的,但每个元素都是examDB
,而不是指向examDB
的指针,所以您只需要释放整个数组。
如果您有类似
的内容,则需要释放数组的每个元素// 1 malloc
examDB** array = malloc(sizeof(examDB*) * 100);
// 100 malloc
for (int i = 0; i < 100; ++i)
examDB[i] = malloc(sizeof(examDB));
...
// 100 free
for (int i = 0; i < 100; ++i)
free(examDB[i]);
// 1 free
free(examDB);
答案 1 :(得分:2)
您分配了一个对象数组。你不能通过元素释放它们。您可以做的只是免费examDB
本身:
free(examDB);
这样做的原因是,正如我之前所说的那样,你正在分配一个完整的空值数组,因为你发布的代码说明了这些:
examDB = malloc(numRecs * sizeof * examDB);
你可以做的是逐个元素释放,就像这样初始化你分配的元素:
for (int i = 0; i < 100; ++i)
examDB[i] = malloc(sizeof(examDB));
Here是malloc
的C ++参考。
提示:我从未见过这样调用此malloc
:
malloc(numRecs * sizeof * examDB);
以这种方式说出来更为常见:
malloc(numRecs * sizeof(examDB));
答案 2 :(得分:1)
您分配了一个包含100个对象的平面数组。然后你试图分别释放每个对象和最后的列表 - 这是当你有一个指向对象的指针数组时使用的模式。在您的情况下,您不能free
只是平面数组中的一个对象。
您有两种选择。保持平面阵列,只需拨打free
一次:
size_t numRecs = 100;
examDB = malloc(numRecs * sizeof * examDB);
free(examDB);
或者将examDB
更改为指向Exam
的指针,以保留指针列表:
Exam **examDB;
然后这将是有效的代码:
size_t numRecs = 100;
examDB = malloc(numRecs * sizeof * examDB);
for (size_t i = 0; i < numRecs; i++) {
examDB[i] = malloc(sizeof ** examDB);
}
for (size_t i = 0; i < numRecs; i++) {
free(&examDB[i]);
}
free(examDB);
顺便说一下,这一定是我见过的最令人困惑的malloc调用之一:
malloc(numRecs * sizeof * examDB)
答案 3 :(得分:0)
examDB = malloc(numRecs * sizeof * examDB); //this allocates the needed memory
此表达式分配numRecs
* sizeof *examDB
的单个连续块,sizeof *examDB
与sizeof struct exam
相同。因此,此时您可以使用 examDB
,就像声明struct exam examDB[numRecs]
一样。
拨打free
的电话应该与拨打malloc
的电话配对,因为您只需malloc
一次,您只需要free
一次。
examDB = malloc(numRecs * sizeof * examDB); //this allocates the needed memory
//...
free(examDB);