C自由动态结构数组 - 为什么它们不是连续的

Pet*_*ete 2 c arrays free struct dynamic

我正在努力使用一个C结构,它必须包含一个动态的较小结构数组:

typedef struct issueStruct {
    int data;
} issue;

typedef struct volumeStruct {
    issue* collection;
    size_t elements;
} volume;
Run Code Online (Sandbox Code Playgroud)

我可以在卷结构的数组中动态创建尽可能多的问题结构.我也可以遍历那个数组:

int main(){
    volume* TimeMagazine = (volume*)malloc(sizeof(volume));
    TimeMagazine->collection = (issue*)malloc(4 * sizeof(issue));
    TimeMagazine->elements = 4;

    issue* ptr = TimeMagazine->collection;
    int i;

    // Populate & iterate through array:
    i = 0;
    while(i < TimeMagazine->elements){
            ptr->data = 100*i;
            printf("%d)  %d\n", i, ptr->data);
            i++;
            ptr = ptr+i;       // Advance ptr
    }
    return 0;
}

OUTPUT:
[Linux]$ gcc -Wall magazines.c
[Linux]$ ./a.out
0)  0
1)  100
2)  200
3)  300
[Linux]$
Run Code Online (Sandbox Code Playgroud)

到现在为止还挺好.当我在GDB中逐步完成上述操作时,一切看起来都没问题,尽管我注意到问题结构似乎没有连续的内存地址.这是我看到的内存地址:

issue 0)  0x602030
issue 1)  0x602034
issue 2)  0x60203c
issue 3)  0x602048
Run Code Online (Sandbox Code Playgroud)

这给了我一些停顿; 我会假设所有问题都是4个字节,如sizeof(issue) = 4.更严重的是,当我修改我的"迭代通过"代码以释放数组的元素时,我的代码会出错.具体来说,它在尝试释放第二个问题时出错.这是代码:

    i = 0;
    ptr = TimeMagazine->collection;
    issue* ptr2 = ptr;
    while(i< TimeMagazine->elements){
            printf("freeing %d...\n", i);
            i++;
            free(ptr2);           // free ptr2
            ptr2 = ptr = ptr+i;   // advance ptr & ptr2
    }
Run Code Online (Sandbox Code Playgroud)

这是错误(Linux上的GCC):

*** Error in `./a.out': free(): invalid pointer: 0x000000000137c034 ***
Run Code Online (Sandbox Code Playgroud)

所以我确定我在这里遗漏了一些东西,但不确定是什么.有人可以推荐一种有效的方法来释放()数组元素吗?

非常感谢!

-Pete

PS - 有许多"阵列中的释放结构"帖子,但似乎没有一个与我正在做的完全匹配.所以我发布这个,希望我的这个问题的版本是独一无二的.

Dav*_*eri 7

while(i < TimeMagazine->elements){
        ptr->data = 100*i;
        printf("%d)  %d\n", i, ptr->data);
        i++;
        ptr = ptr+i;       // Advance ptr
}
Run Code Online (Sandbox Code Playgroud)

您正在使用错误的指针算法ptr = ptr+i,应该是ptr = ptr+1您在边界外访问.该free部分也是如此.

正如@kaylum在评论中所指出的那样:你free在一个循环中调用,这也是错误的,你可以free(TimeMagazine->collection);立刻就可以为4同一个块中的元素保留空间.

  • 另一个问题似乎是一个`malloc`而是多个`free`s. (2认同)