0

请看c代码并帮助我。为什么我有“free(): invalid next size (fast)”?我尝试了 valgrind,但不明白,有太多“无效的写入/读取 ....”,但如果我评论 free_array(all) a 有正确的答案。它只是所有代码的一部分。

#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;
}
4

2 回答 2

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结构时,您已经为 each 分配了内存pair,无需一一分配,尤其是因为您只是丢弃了指针,因此存在内存泄漏。

释放时,只需释放array结构,因为这就是您(应该)分配的所有内容。

于 2013-10-19T19:56:54.107 回答
0

Joachim 给出了正确答案,但原始“sizeof_array()”不正确的原因是“struct array”包含“struct pair”而不是“uint32_t”的数组。并且该结构是“sizeof(uint32_t)”的两倍。

此外,虽然不太可能,但某些平台上的编译器可能会在“结构对”中添加额外的对齐空间。

于 2013-10-19T20:16:27.493 回答