Patrick Resal
Patrick Resal

Reputation: 125

Malloc with int **

if I have as an argument int **a in my function I was wondering what is the difference between a = (int **)malloc(sizeof(a)*(length) and *a = (int *)malloc(sizeof(a)*(length) I've discovered malloc last week so I don't understand everything yet. Thank you !

Upvotes: 3

Views: 4806

Answers (4)

Galaxy
Galaxy

Reputation: 1279

malloc just returns a void * pointer, nothing more.

a is a pointer to pointer.

The right side of the Equals Sign is not important here, so leave the right side alone. Now we got:

// 1st code fragment
int **a1;
// Asign a null pointer to a1, now a1 is a NULL pointer
a1 = (int **)NULL;

// 2rd code fragment
int **a2;
// Asign a null pointer to the pointer pointed by a2.
// Here may crash actually, because a2 is not initialized yet.
*a2 = (int *)NULL;

Upvotes: 4

Floris
Floris

Reputation: 518

I think the following will answer your question, but I am not 100% sure. Let's find out!

You mention 'my function', which makes me think that you are not referring to your main function, but that you are writing a function (perhaps to allocate a). If that is the case, the difference is the following; a simple variable int a in the argument list of a function will be passed by value. That means that if you call the function, say void foo(int x), with a certain value, that value will be copied to the function. Therefore, when you enter the function, you are not working with the actual variable; instead, you are working with a copy. Where a particular variable exists and where it does not, is referred to as a variable's scope.

Now to your practical case: I presume you want to allocate an array in a function. If you use your first example: a = (int **)malloc(sizeof(a)*(length) in a function where a is an argument, the same thing will happen as I outlined above. I.e., a gets copied to the function and then you allocate it there. However, when your function ends, a is destroyed (note: the pointer that is, the memory is not freed correctly)! If my assumption is correct, this will probably not be the desired result.

By contract, if your function has int *a as an argument, the argument will be passed by address. Now, any changes you make (by dereferencing a using the * operator), will persist even when you return to the place where your function was called.

Upvotes: 0

satyaGolladi
satyaGolladi

Reputation: 192

int **a;

a is of type integer double pointer.

a = (int **) malloc(sizeof(a)*(length));

uninitialized memory of size sizeof(a)*(length) allocated to a upon malloc success.

*a = (int )malloc(sizeof(a)(length);

uninitialized memory of size sizeof(a)*(length) allocated to a[0] (if a initialized only other wise it crashes) upon malloc success.

Note: sizeof(a) is sizeof double pointer, it is 4 bytes for 32 bit mechine. So allocating same memory i.e sizeof(a)*(length) memory in both cases may not be correct.

Upvotes: 1

Tim Randall
Tim Randall

Reputation: 4145

The first case takes the address of the memory allocated by the call to malloc, and assigns it to your variable a. The second takes the address of the memory allocated by malloc and stores that in whatever memory a happens to be pointing at.

There's another question here, though, which is specifying how much memory you should allocate. If you want a to store an array of pointers to integers, I would use expression a = (int**) malloc( length * sizeof(*a) ); which makes it clear that you are allocating space for a number of integer pointers.

On the other hand, if you want to allocate space for a number of integers (not pointers) and you are sure that a is pointing at a variable of type int*, then use the expression *a = (int*) malloc( length * sizeof *(*a) );

Finally, note that (per chux's link below) it is unnecessary and not recommended to cast the result of malloc(). I have left in the casts here only for clarity, because they illustrate that we're storing the returned value in a different type of variable in each case.

Upvotes: 1

Related Questions