views:

442

answers:

3

Hello all,

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


#include                        
#include                       
#include                       

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.

+1  A: 

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.

Alan
Better is: malloc( sizeof *test1 );
William Pursell
+5  A: 

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;
Inshallah
A: 

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.

Richard Berg