调用免费时出错:双重免费或损坏,损坏的大小与 prev_size,收到信号 6
Error on calling free: double free or corruption, corrupted size vs. prev_size, received signal 6
我在分配的内存块上调用 free 时收到错误。
根据我的代码,我得出以下 MWE:
(注意,free被注释掉了,调用会报错)
#include <stdio.h>
#include <malloc.h>
typedef struct foo1 {
double v1;
double v2;
double v3;
} foo1;
typedef struct foo2 {
foo1* myfoo1s;
int num_foo1;
} foo2;
void init_and_set_v1(foo2** myfoo2, int a_num){
*myfoo2 = malloc(sizeof(foo2));
(*myfoo2)->num_foo1 = a_num;
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo2) );
for(int i = 0; i < (*myfoo2)->num_foo1; i ++){
(*myfoo2)->myfoo1s[i].v1 = 1.0;
}
//free( (*myfoo2) -> myfoo1s); //location 1
}
void set_v2_and_v3(foo2* myfoo2){
for(int i = 0; i < myfoo2->num_foo1; i ++){
myfoo2->myfoo1s[i].v2 = 2.0;
myfoo2->myfoo1s[i].v3 = 3.0;
}
//free(myfoo2->myfoo1s); //location 2
}
int main(){
foo2* myfoo2;
init_and_set_v1(&myfoo2, 10);
set_v2_and_v3(myfoo2);
printf("%d\n", myfoo2->num_foo1);
// ... do other things
//free(myfoo2->myfoo1s); //location 3
printf("done.");
return 0;
}
我有一个结构 foo2,它包含一个指向结构数组 foo1 的指针。我使用不同的函数分配内存和初始化变量,因为在我的用例中,我需要解析不同的数据文件。我不想有一个巨大的代码块。
但是,当我拨打免费电话时,我收到错误消息。我使用 GCC 7.5.0。
对于可能导致此问题的原因,我将不胜感激。
P.S。在我的原始程序中,错误取决于调用 free 的位置。在这个 MWE 中,它不是。
非常感谢。
您分配的内存量有误:
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo2) );
您想创建一个 foo1
的数组,但您在这里使用 sizeof(foo2)
为 foo2
的数组分配 space。由于 foo2
小于 foo1
,您写入已分配内存的末尾触发 undefined behavior
将此更改为:
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo1) );
并且在 完成使用之前不要调用 free
,在这种情况下,“位置 3”是您想要释放两者的地方 myfoo2->myfoo1s
和 myfoo2
.
P.S。我在我的原始代码中找到了问题的根本原因——独立于 MWE。该错误是由 两次释放分配的内存 引起的。在进一步追踪问题之后,GCC 打印出错误 free(): double free detected in tcache 2,这让我走上了正确的轨道。
我在分配的内存块上调用 free 时收到错误。 根据我的代码,我得出以下 MWE:
(注意,free被注释掉了,调用会报错)
#include <stdio.h>
#include <malloc.h>
typedef struct foo1 {
double v1;
double v2;
double v3;
} foo1;
typedef struct foo2 {
foo1* myfoo1s;
int num_foo1;
} foo2;
void init_and_set_v1(foo2** myfoo2, int a_num){
*myfoo2 = malloc(sizeof(foo2));
(*myfoo2)->num_foo1 = a_num;
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo2) );
for(int i = 0; i < (*myfoo2)->num_foo1; i ++){
(*myfoo2)->myfoo1s[i].v1 = 1.0;
}
//free( (*myfoo2) -> myfoo1s); //location 1
}
void set_v2_and_v3(foo2* myfoo2){
for(int i = 0; i < myfoo2->num_foo1; i ++){
myfoo2->myfoo1s[i].v2 = 2.0;
myfoo2->myfoo1s[i].v3 = 3.0;
}
//free(myfoo2->myfoo1s); //location 2
}
int main(){
foo2* myfoo2;
init_and_set_v1(&myfoo2, 10);
set_v2_and_v3(myfoo2);
printf("%d\n", myfoo2->num_foo1);
// ... do other things
//free(myfoo2->myfoo1s); //location 3
printf("done.");
return 0;
}
我有一个结构 foo2,它包含一个指向结构数组 foo1 的指针。我使用不同的函数分配内存和初始化变量,因为在我的用例中,我需要解析不同的数据文件。我不想有一个巨大的代码块。
但是,当我拨打免费电话时,我收到错误消息。我使用 GCC 7.5.0。 对于可能导致此问题的原因,我将不胜感激。
P.S。在我的原始程序中,错误取决于调用 free 的位置。在这个 MWE 中,它不是。
非常感谢。
您分配的内存量有误:
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo2) );
您想创建一个 foo1
的数组,但您在这里使用 sizeof(foo2)
为 foo2
的数组分配 space。由于 foo2
小于 foo1
,您写入已分配内存的末尾触发 undefined behavior
将此更改为:
(*myfoo2)->myfoo1s = malloc( (*myfoo2)->num_foo1 * sizeof(foo1) );
并且在 完成使用之前不要调用 free
,在这种情况下,“位置 3”是您想要释放两者的地方 myfoo2->myfoo1s
和 myfoo2
.
P.S。我在我的原始代码中找到了问题的根本原因——独立于 MWE。该错误是由 两次释放分配的内存 引起的。在进一步追踪问题之后,GCC 打印出错误 free(): double free detected in tcache 2,这让我走上了正确的轨道。