错误的Malloc()三层结构



我正在做一个C程序(Linux, GCC)与三层结构:

typedef struct innerThing{
    int data;
} inner;
typedef struct middleThing{
    size_t elements;
    inner collection[];
} middle;
typedef struct outerThing{
    size_t outerElements;
    size_t totalElements;
    middle collection[];
} outer;
使用这个网站上的其他帖子,我拼凑了应该构建这些结构的2D系统的代码。当我使用malloc()方法获取所需的空间,然后遍历它时,一切看起来都很好:
int main(){
    outer* outerThing = (outer*)malloc(sizeof(outer) + (4*sizeof(middle)) * (6*sizeof(inner)) );
    outerThing->totalElements = 4 * 6;
    outerThing->outerElements = 4;
    int i, j;
    middle* ptr1;
    inner*  ptr2;
    // Have to manually set the "elements" metadata for middle structs
    for(i=0, ptr1 = outerThing->collection; i<outerThing->outerElements;  ptr1=ptr1+1, i++){
            ptr1->elements = 6;
    }
    for(i=0, ptr1=outerThing->collection;  i<outerThing->outerElements;  ptr1=ptr1+1, i++){
            for(j=0, ptr2=ptr1->collection;  j<ptr1->elements;  ptr2=ptr2+1, j++){
                    printf(".");
            }
            printf("n");
    }
    free(outerThing);
    return 0;
}

输出是:

[Linux]$ gcc -Wall threeStructs.c
[Linux]$ ./a.out
......
......
......
......
[Linux]$

非常鼓励…虽然我原以为是四列,每列六颗星。也许这是第一个问题。然而,让我抓狂的是,当我修改嵌套循环以插入数据时:

    for(i=0, ptr1=outerThing->collection;  i<outerThing->outerElements;  ptr1=ptr1+1, i++){
            for(j=0, ptr2=ptr1->collection;  j<ptr1->elements;  ptr2=ptr2+1, j++){
                    printf(".");
                    ptr2->data=0;      // <<< Added
            }
            printf("n");
    }

现在程序的行为改变了。当我重新运行它时,我看到如下:

[Linux]$ gcc -Wall threeStructs.c
[Linux]$ ./a.out
......

[Linux]$

我已经用GDB完成了这一步,我注意到第一个内部循环运行得很好。然而,剩余的内部循环永远不会运行,因为ptr1->elements以某种方式从6覆盖到0。当我将ptr2->data线设置为9或7或I +j时,程序段故障;

ptr1->elements从0覆盖到12898794682。

我确信当我在内部结构中设置数据时,它以某种方式覆盖了中间结构中的数据。如果我必须大胆猜测,这是因为我的malloc()调用太原始了吗?我应该malloc()外部结构,然后中间结构,然后循环内部结构吗?如果是这样,在循环中执行malloc()是否有任何危险?我认为这是C编程的禁忌。

谢谢!皮特

我无法让这个工作。我只需要两层结构体就可以让它工作,但不需要三层。

然而,我想到我只有一个外部结构体。所以我用一个数组代替了它,在main()中声明。语义有点奇怪,但这个解决方案是有效的。下面是代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define NUM_SETS  10
#define NUM_LINES 20
typedef struct innerStruct {
    int data;
} inner;
typedef struct middleStruct {
    size_t elements;
    inner collection[];
} middle;
int main(){
    middle* arr[NUM_SETS];
    inner* ptr;
    int i, j;
    // set up the array
    for(i=0; i<NUM_SETS; i++){
            arr[i] = (middle*)malloc(sizeof(middle) + (NUM_LINES * sizeof(inner)) );
            arr[i]->elements = NUM_LINES;
    }
    // Test populate the array
    for(i=0; i<NUM_SETS; i++){
            for(j=0, ptr=arr[i]->collection;  j<NUM_LINES; j++, ptr=ptr+1){
                    ptr->data=i+j;    // or whatever
            }
    }
    // free everything
    for(i=0; i<NUM_SETS; i++){
            free(arr[i]);
    }
    return 0;
}

相关内容

  • 没有找到相关文章