systemsfault
systemsfault

Reputation: 15547

Pointer to struct within the nested structs

I'm trying to run the following code(in gcc 4.3 on fedora 11 i586 ):

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

But I got a segfault at test1->test2[0].smallstruct[0].smallstruct = 123; . Commented part is running without error. What is the reason of this behaviour. I'm not very proficient in C , so I'd appreciate any kind of help.

Upvotes: 3

Views: 7901

Answers (4)

LED Fantom
LED Fantom

Reputation: 1373

I compiled the code marked as correct chosen by the question poster, @systemsfault , but got core dumped. I hope to have a healthy and helpful discuss here to give the right solution for the question. I am also pretty new to stackoverflow, so if I say anything wrong, please feel free to correct me. Now, here we go...

Since the old solution didn't complile, there're 2 steps I tried to fix it. First, I added for loops, but still got core dumped caused by (a1) and (a2).

Next, I used lines (b1) and (b2) to replace (a1) and (a2). Now it compiled and runs correctly.

I have cleaned up the structs to make it simplier to read:

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

Upvotes: 0

Inshallah
Inshallah

Reputation: 4814

There are three problems with your code that I can see:

  1. sizeof only tells you the size of the pointer, which is 4 for 32-bit pointers, not the size of the structure that is pointed to,
  2. and even if you change sizeof to tell you the size of the structure, malloc will only allocate memory for the s_test1 structure, not for the structures that are pointed to from within it,
  3. and finally, the pointers in test1, test2 etc. have to be initialized.

Here is something that works:

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;

Upvotes: 7

Richard Berg
Richard Berg

Reputation: 20782

You are not allocating any memory for the inner structs. sizeof(test1) only has enough room for 3 pointers, not the entire struct of structs.

Plus, that statement has 5 (!) dereference operators in it. Even if you had allocated a big enough chunk of memory, you haven't laid things out in a way that ensures it's contiguous -- you are asking it hop from block to block 5 times.

Upvotes: 1

Alan
Alan

Reputation: 13731

Try changing:

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

to

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

test1 is a pointer, which in 32bit environments is 4 bytes.

Upvotes: 1

Related Questions