Reputation: 125
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
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
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
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
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