Reputation: 15547
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
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
Reputation: 4814
There are three problems with your code that I can see:
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
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
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