请查看c代码并帮助我。为什么我有“免费():无效的下一个大小(快)”?我尝试valgrind,但不明白,有太多“无效的写/读....”,但如果我评论free_array(全部)一个有正确的答案。它只是所有代码的一部分。
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
#include <stdlib.h>
struct pair {
uint32_t num;
uint32_t effect;
};
struct array {
size_t size;
struct pair data[];
};
size_t sizeof_array(size_t size)
{
return sizeof(struct array) + (size * sizeof(uint32_t));
}
struct pair *create_pair(uint32_t i, uint32_t eff)
{
struct pair *ret = calloc(2, sizeof(uint32_t));
if (! ret)
abort();
ret->num = i;
ret->effect = eff;
return ret;
}
struct array *create_array(size_t size)
{
struct array *ret = calloc(1, sizeof_array(size));
if (! ret)
abort();
ret->size = size;
return ret;
}
void free_array(struct array *array)
{
// size_t i;
// for (i = 0; i < array->size; ++i) {
// free(&array->data[i]);
// }
free(array);
}
int main()
{
int eff;
size_t n;
scanf("%zu", &n);
struct array *all = create_array(n);
size_t i;
for(i = 0; i < n; ++i) {
scanf("%d", &eff);
all->data[i] = *create_pair(i, eff);
}
free_array(all);
return 0;
}
答案 0 :(得分:1)
就像我在评论中所说的那样,在分配内存时不要使用结构的每个成员的大小作为基础,使用实际的结构。这是您的问题的原因,因为您的函数sizeof_array
返回的大小大约是您需要的大小的一半。
相反它应该看起来像
size_t sizeof_array(size_t size)
{
return sizeof(struct array) + (size * sizeof(struct pair));
/* Notice the use of the structure instead ^^^^^^^^^^^ */
}
因为sizeof_array
返回的字符太小,所以分配的内存太少,写入超出了已分配内存的范围,然后以未定义的行为结束。
当您为阵列中的每个struct pair
分配内存时,也会发生内存泄漏。当您分配array
结构时,您已经为每个pair
分配了内存,因此不需要逐个分配内存,尤其是因为您只是丢弃指针并因此导致内存泄漏。
在释放时,只需释放array
结构,就像你应该分配的一样。
答案 1 :(得分:0)
Joachim给出了正确答案,但原始“sizeof_array()”不正确的原因是因为“struct array”包含一个“struct pair”而不是“uint32_t”的数组。结构的大小是“sizeof(uint32_t)”的两倍。
此外,虽然不太可能,但某些平台上的编译器可能会在“struct pair”中为对齐添加额外的空间。