指向嵌套结构体中的结构体指针

3

我正在尝试运行以下代码(在fedora 11 i586上的gcc 4.3中):

#include <stdio.h>                       
#include <stdint.h>                      
#include <stdlib.h>                      

struct s_smallstruct{
  int smallstruct;
};                      

struct s_test2{
        char * test2;
        struct s_smallstruct* smallstruct;
};

struct s_test3{
        char * test3;
        struct s_smallstruct * smallstruct;
};

struct s_test1{
        char * test1;
        struct s_test2 * test2;
        struct s_test3 * test3;
};


int main(){
        struct s_test1 *test1 = (struct s_test1 *) malloc( sizeof test1 );
        test1->test2[0].smallstruct[0].smallstruct = 123;
        int num = test1->test2[0].smallstruct[0].smallstruct;
//      struct s_smallstruct * smallstruct = (struct s_smallstruct *) malloc( sizeof smallstruct );
//      smallstruct[0].smallstruct =12;
//      int num =  smallstruct[0].smallstruct;
        printf( "%d\n" , num );
        return EXIT_SUCCESS;
}

但是在 test1->test2[0].smallstruct[0].smallstruct = 123; 处发生了段错误。被注释的部分没有错误。这种行为的原因是什么。我对C语言不是很熟练,所以希望得到任何帮助。


这不是一个解决方案,但始终要检查*ALLOC!! - user487868
4个回答

7
我看到你的代码有三个问题:
  1. sizeof 只能告诉你指针的大小,对于32位指针来说是4,而不能告诉你所指向的结构体的大小。
  2. 即使你将 sizeof 更改为告诉你结构体的大小,malloc 也只会为 s_test1 结构体分配内存,而不会为其中指向的结构体分配内存。
  3. 最后,test1test2 等指针必须被初始化。
这里是一个可行的代码:
const int length = 2;    
struct s_test1 *test1 = malloc( length * sizeof *test1 );
test1->test2 = malloc( length * sizeof *test1->test2 );
test1->test2->smallstruct = malloc( length * sizeof *test1->test2->smallstruct );
test1[1].test2[0].smallstruct[1].smallstruct = 123;
int num = test1[1].test2[0].smallstruct[1].smallstruct;

1

尝试更改:

struct s_test1 *test1 = (struct s_test1 *) malloc( sizeof test1 );

struct s_test1 *test1 = (struct s_test1 *) malloc( sizeof struct s_test1 );

test1是一个指针,在32位环境中为4个字节。


更好的写法是:malloc(sizeof *test1); - William Pursell

1

你没有为内部结构分配任何内存。sizeof(test1)只有足够的空间容纳3个指针,而不是整个结构体。

此外,该语句中有5个(!)解引用运算符。即使您已经分配了足够大的内存块,您也没有以确保连续性的方式布置它--您要求它在块之间跳跃5次。


0

我编译了由问题发布者@systemsfault标记为正确的代码,但是出现了核心转储。我希望在这里进行健康和有益的讨论,以给出正确的解决方案。我也是stackoverflow的新手,如果我说错了什么,请随时纠正我。现在,我们开始吧...

由于旧的解决方案无法编译,我尝试了两个步骤来修复它。首先,我添加了for循环,但仍然由(a1)和(a2)导致核心转储。

接下来,我使用(b1)和(b2)行替换了(a1)和(a2)。现在它已经编译并且运行正确。

我已经清理了结构体,使其更易于阅读:

#include <stdio.h>                       
#include <stdlib.h>                      

struct s_smallstruct{
  int smallstruct;
};                      

struct s_test2{
  struct s_smallstruct *smallstruct;
};

struct s_test1{
  struct s_test2 *test2;
};

int main() {
  int i, j, length = 2;    

  struct s_test1 *test1 = malloc( length * sizeof *test1 );

  for (i=0; i<length; i++) {
    //test1[i].test2 = malloc( length * sizeof *test1->test2 );//(a1)
    test1[i].test2 = malloc( length * sizeof *test1[i].test2 );//(b1)

    for (j=0; j<length; j++) {
      //test1[i].test2[i].smallstruct = malloc( length * sizeof *test1->test2->smallstruct );//(a2)
      test1[i].test2[j].smallstruct = malloc( length * sizeof *test1[i].test2[j].smallstruct );//(b2)
    }
  }

  test1[1].test2[0].smallstruct[1].smallstruct = 123;
  int num = test1[1].test2[0].smallstruct[1].smallstruct;
  printf("num:%d\n", num);
  return 0;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接