如何在c中释放动态分配的结构数组?

时间:2016-10-01 22:44:07

标签: c arrays struct

我正在学习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来创建数组......我在这里缺少什么?

4 个答案:

答案 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));

Heremalloc的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 *examDBsizeof struct exam相同。因此,此时您可以使用 examDB,就像声明struct exam examDB[numRecs]一样。

拨打free的电话应该与拨打malloc的电话配对,因为您只需malloc一次,您只需要free一次。

 examDB = malloc(numRecs * sizeof * examDB); //this allocates the needed memory
 //...
 free(examDB);