[英]How to free a dynamically allocated array of structs in c?
I am learning C and I can't free a dynamically allocated array of structs. 我正在学习C,无法释放动态分配的结构体数组。 Here is my sample code:
这是我的示例代码:
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);
}
When I compile this for windows, everything works fine (it seems). 当我为Windows编译时,一切正常(看来)。 When I compile the same piece of code on my mac using xcode, I get an error that says: "malloc: *** error for object 0x7fae610060d0: pointer being freed was not allocated"
当我使用xcode在Mac上编译同一段代码时,出现错误消息:“ malloc:对象0x7fae610060d0的错误:未分配释放的指针”
How is that possible? 那怎么可能? I used malloc to create the array... What am I missing here?
我使用malloc创建了数组...我在这里想念什么?
You need a free
for each malloc
. 您需要为每个
malloc
free
。 How many malloc
s you have? 您有多少个
malloc
? 1, so how many free
you need? 1,您需要多少
free
? Just 1. 只是1。
You are allocating an array of 100 * sizeof(examDB)
elements, which is dynamic but each element is a examDB
, not a pointer to an examDB
so you just need to free the whole array. 您正在分配一个由
100 * sizeof(examDB)
元素组成的数组,该数组是动态的,但每个元素都是一个examDB
,而不是指向examDB
的指针,因此您只需要释放整个数组即可。
You would have required to free each element of the array if you had something like 如果您有类似的东西,您将需要释放数组的每个元素
// 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);
You allocated an array of objects. 您分配了一个对象数组。 You can't free them by elements.
您不能按元素释放它们。 What you can do is just free
examDB
itself: 您可以做的就是免费的
examDB
本身:
free(examDB);
The reason to do this is, as I said before, you are allocating a whole array of null values, as this code you posted states: 这样做的原因是,正如我之前说的,您正在分配整个空值数组,因为您发布的这段代码指出:
examDB = malloc(numRecs * sizeof * examDB);
What you can do to free element by element is to initialize your allocated elements like this: 要释放一个元素一个元素,您可以做的是初始化分配的元素,如下所示:
for (int i = 0; i < 100; ++i)
examDB[i] = malloc(sizeof(examDB));
Here is a C++ reference for malloc
. 这是
malloc
的C ++参考。
Tip : I have never seen this malloc
invoked like this: 提示 :我从未见过这样调用过
malloc
:
malloc(numRecs * sizeof * examDB);
It's more common to put it this way: 这种说法更常见:
malloc(numRecs * sizeof(examDB));
You allocated a flat array of 100 objects. 您分配了100个对象的平面数组。 You're then trying to free each object separately and the list at the end - that's a pattern used when you have an array of pointers to objects.
然后,您尝试分别释放每个对象,最后释放列表-这是当您有指向对象的指针数组时使用的模式。 In your case, you can't
free
just one object in a flat array. 就您而言,不能只
free
平面数组中的一个对象。
You have two options. 您有两个选择。 Keep the flat array and just call
free
once: 保留平面数组,只需拨打一次
free
电话:
size_t numRecs = 100;
examDB = malloc(numRecs * sizeof * examDB);
free(examDB);
Or change examDB
to a pointer to pointer to Exam
to keep a list of pointers: 或将
examDB
更改为指向Exam
指针,以保留指针列表:
Exam **examDB;
and then this would be the valid code: 然后这将是有效的代码:
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);
BTW, this must be one of the most confusing malloc invocations I've ever seen: 顺便说一句,这一定是我见过的最令人困惑的malloc调用之一:
malloc(numRecs * sizeof * examDB)
examDB = malloc(numRecs * sizeof * examDB); //this allocates the needed memory
This expression allocates a single contiguous block of numRecs
* sizeof *examDB
, and sizeof *examDB
is the same as sizeof struct exam
. 该表达式分配一个连续的
numRecs
* sizeof *examDB
块,而sizeof *examDB
与sizeof struct exam
相同。 So at this point you can use examDB
much in the same way as if it was declared struct exam examDB[numRecs]
. 因此,在这一点上,您可以像使用
struct exam examDB[numRecs]
一样使用 examDB
。
Calls to free
should be paired with calls to malloc
and since you only malloc
once, you only need to free
once. 对
free
调用应与对malloc
调用配对使用,并且由于您仅对malloc
一次,因此只需对free
一次调用。
examDB = malloc(numRecs * sizeof * examDB); //this allocates the needed memory
//...
free(examDB);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.