2

I implemented this function to create a tree of dept d and with branch factor b:

void create(node *n, int b, int d){
int cont,i;


if(d>0){
    n->children = (node *) malloc(b*sizeof(node));

    if(!n->children){
        printf("\n\nMemory couldn't be allocated\n");
        getchar();
        return;
    }
    n->alpha = -100;

    for(i=0;i<b;i++){
        create((n->children+i*sizeof(node)), b, d-1);   

    }
}
else if(d==0){
    if(n){
        n->alpha = rand()%9 + 1;
        printf("%d  ",n->alpha);
    }

}

It works fine for d<6 and b<6, but when b =6 and d=6, or bigger, it gives me a segmentation fault.

But when I change the line create((n->children+i*sizeof(node)), b, d-1); for the line create((&n->children[i]), b, d-1);, it works perfectly for any d and b, as far as I have tested. But the two lines truly are the same!!! just the address of the children struct.... So, does anybody know why is it happening? Doesn't malloc allocates one contiguous block of memory?

this thing really made me confused!! pls, help!

Thanks =) ,

Ingrid

Joe
  • 46,419
  • 33
  • 155
  • 245
igalvez
  • 145
  • 2
  • 10
  • 3
    `n->children+i` is equivalent to `&n->children[i]` . just remove the * sizeof – SHR Oct 30 '13 at 16:52
  • http://ideone.com/uPwIG7 As you can see here, the pointer arithmetic already takes care of the object size in the computation – Rerito Oct 30 '13 at 16:54
  • 1
    @SHR that is the answer, clearly. I was about to type it up, but post it and I'll up-vote and move on. – WhozCraig Oct 30 '13 at 16:55
  • 1
    OT: In C it is not necessary nor recommended to cast `malloc/calloc/realloc`: http://stackoverflow.com/a/605858/694576 – alk Oct 30 '13 at 18:12

1 Answers1

1

you have answer your question. :D

But when I change the line create((n->children+i*sizeof(node)), b, d-1); for the line create((&n->children[i]), b, d-1);, it works perfectly for any d and b, as far as I have tested. But the two lines truly are the same!!! just the address of the children struct

The two lines are NOT the same as the pointer arithmetic takes into account the type of the object and it correctly adjustes the resulting address with the size of that object type. So :

   n->children+i === &n->children[i]

both get translate to (n->children)+ (i * sizeof(struct node)) while, your code :

(n->children+i*sizeof(node)

gets translate to (n->children)+ (i * sizeof(struct node))*sizeof(struct node). The first sizeof operator is added wrongly added by you, while the second is automatically by the pointer arithmetic.

It works fine for d<6 and b<6, but when b =6 and d=6, or bigger, it gives me a segmentation fault.

It worked for small number because the malloc function maps more memory in the process space than that required for performance reasons. You got a segmentation fault, when you exceeded the memory area correctly mapped.

Doesn't malloc allocates one contiguous block of memory?

Yes, malloc allocates a continuos memory block.

Giuseppe Pes
  • 7,772
  • 3
  • 52
  • 90