2

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 !

Patrick Resal
  • 115
  • 2
  • 11
  • 2
    With `int **a`, ask "what is the difference between `a` and `*a`?" – chux - Reinstate Monica Aug 21 '18 at 13:28
  • 3
    Note that `sizeof(a)` is unlikely to be what you want in either case. What you want instead depends on which variant you choose. – John Bollinger Aug 21 '18 at 13:29
  • 1
    If you just now are learning this, you might want to get it right from the start: [Correctly allocating multi-dimensional arrays](https://stackoverflow.com/questions/42094465/correctly-allocating-multi-dimensional-arrays). Otherwise some poor soul has to spend time deprogramming you, when you become a professional programmer. – Lundin Aug 21 '18 at 13:55

4 Answers4

3

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;
Galaxy
  • 1,129
  • 11
  • 27
1

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.

Tim Randall
  • 4,040
  • 1
  • 17
  • 39
0

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.

satyaGolladi
  • 180
  • 13
-1

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.

Floris
  • 508
  • 2
  • 9
  • there is no `std::` in `C` – Fureeish Aug 21 '18 at 13:48
  • 2
    C++ examples are not particularly welcome in questions tagged [c], your assertion of relevance notwithstanding. Beyond that, although scope may indeed be relevant to the OP's situation, it is not directly relevant to the actual question. – John Bollinger Aug 21 '18 at 13:53
  • Good points, I'll remove the example and leave the last two paragraphs. – Floris Aug 21 '18 at 13:56