2
votes

I'm trying to understand the below, how these 3 function calls are working with no problems, I'm not sure how it works internally, I can understand the first one just fine, but the second time I called malloc with the sizeof the struct then print it, the third time I called malloc with the sizeof the pointer of the structure and also print it. how both can work with no problems? The second malloc allocates the size of 2*2*int=16 bytes and the third malloc allocates be 2*pointer=8. And also I'm getting core dump when trying to free pt2, this is on Linux using C & gcc

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

struct test{
 int field1; 
 int field2;  
};


struct test func(int a, int b) {
 struct test t;
 t.field1 = a;
 t.field2 = b;
 return t;
}

  int main()
{

struct test t;


struct test  pt[2];
pt[0] = func(1,1);
pt[1] = func(2,2);
printf("%d %d\n", pt[0].field1,pt[0].field2);
printf("%d %d\n", pt[1].field1,pt[1].field2);

printf("\n");

struct test *pt1;
pt1 = malloc(sizeof(struct test) * 2);
pt1[0] = func(2,2);
pt1[1] = func(3,3);
printf("%d %d\n", pt1[0].field1,pt1[0].field2);
printf("%d %d\n", pt1[1].field1,pt1[1].field2);
printf("\n");


struct test *pt2;
pt2 = malloc(sizeof(struct test*) * 2);
pt2[0] = func(4,4);
pt2[1] = func(5,5);
printf("%d %d\n", pt2[0].field1,pt2[0].field2);
printf("%d %d\n", pt2[1].field1,pt2[1].field2);

free(pt1);
free(pt2);// I'm getting core dump when trying to free pt2

}

output is below

1 1
2 2

2 2
3 3

4 4
5 5
2

2 Answers

3
votes
pt1 = malloc(sizeof(struct test) * 2);

This statement is correct.

pt2 = malloc(sizeof(struct test*) * 2);

This statement is wrong. It uses the wrong type in the sizeof expression and consequently allocates the wrong amount of memory. It's common practice to use sizeof(*var) rather than sizeof(type) to avoid exactly this problem.

pt2 = malloc(sizeof(*pt2) * 2);

On a 32-bit platform like yours the faulty malloc allocates only half the required amount of memory, so the assignment to p2[1] invokes undefined behavior. Your program writes to memory it does not own. This being C, there is little runtime error checking. Rather than immediately crashing you'll often just overwrite whatever happens to be in memory next to the malloc'ed block.

Buffer overruns are a silent killer. Who knows what you just overwrote? It could be anything, really. It's no surprise that trying to free pt2 triggers a core dump. Pointer errors are nasty in C because so often your program will limp along for a while before finally crashing. The code that crashes isn't necessarily where the bug is.

1
votes

You're not allocating enough space for pt2. The statement:

pt2 = malloc(sizeof(struct test*) * 2)

is only allocating space for two pointers to the struct, not enough space for the struct's themselves.

You're writing past the bounds of the pt2 array. This is undefined behaviour, and in your case results in crash on free. If this were part of a more complex program, this type of issue might result in different sorts of memory corruption...