7

When shall i use malloc instead of normal array definition in C?

I can't understand the difference between:

int a[3]={1,2,3}
int array[sizeof(a)/sizeof(int)]

and:

array=(int *)malloc(sizeof(int)*sizeof(a));
Antonio Ciccia
  • 726
  • 3
  • 8
  • 18

4 Answers4

21

In general, use malloc() when:

  • the array is too large to be placed on the stack
  • the lifetime of the array must outlive the scope where it is created

Otherwise, use a stack allocated array.

hmjd
  • 120,187
  • 20
  • 207
  • 252
6
int a[3]={1,2,3}
int array[sizeof(a)/sizeof(int)]

If used as local variables, both a and array would be allocated on the stack. Stack allocation has its pros and cons:

  • pro: it is very fast - it only takes one register subtraction operation to create stack space and one register addition operation to reclaim it back
  • con: stack size is usually limited (and also fixed at link time on Windows)

In both cases the number of elements in each arrays is a compile-time constant: 3 is obviously a constant while sizeof(a)/sizeof(int) can be computed at compile time since both the size of a and the size of int are known at the time when array is declared.

When the number of elements is known only at run-time or when the size of the array is too large to safely fit into the stack space, then heap allocation is used:

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

As already pointed out, this should be malloc(sizeof(a)) since the size of a is already the number of bytes it takes and not the number of elements and thus additional multiplication by sizeof(int) is not necessary.

Heap allocaiton and deallocation is relatively expensive operation (compared to stack allocation) and this should be carefully weighted against the benefits it provides, e.g. in code that gets called multitude of times in tight loops.

Modern C compilers support the C99 version of the C standard that introduces the so-called variable-length arrays (or VLAs) which resemble similar features available in other languages. VLA's size is specified at run-time, like in this case:

void func(int n)
{
   int array[n];
   ...
}

array is still allocated on the stack as if memory for the array has been allocated by a call to alloca(3).

Hristo Iliev
  • 72,659
  • 12
  • 135
  • 186
4

You definately have to use malloc() if you don't want your array to have a fixed size. Depending on what you are trying to do, you might not know in advance how much memory you are going to need for a given task or you might need to dynamically resize your array at runtime, for example you might enlarge it if there is more data coming in. The latter can be done using realloc() without data loss.

Instead of initializing an array as in your original post you should just initialize a pointer to integer like.

int* array; // this variable will just contain the addresse of an integer sized block in memory
int length = 5; // how long do you want your array to be;

array = malloc(sizeof(int) * length); // this allocates the memory needed for your array and sets the pointer created above to first block of that region;

int newLength = 10;
array = realloc(array, sizeof(int) * newLength); // increase the size of the array while leaving its contents intact;
inVader
  • 1,504
  • 14
  • 25
1

Your code is very strange.

The answer to the question in the title is probably something like "use automatically allocated arrays when you need quite small amounts of data that is short-lived, heap allocations using malloc() for anything else". But it's hard to pin down an exact answer, it depends a lot on the situation.

Not sure why you are showing first an array, then another array that tries to compute its length from the first one, and finally a malloc() call which tries do to the same.

Normally you have an idea of the number of desired elements, rather than an existing array whose size you want to mimic.

The second line is better as:

int array[sizeof a / sizeof *a];

No need to repeat a dependency on the type of a, the above will define array as an array of int with the same number of elements as the array a. Note that this only works if a is indeed an array.

Also, the third line should probably be:

array = malloc(sizeof a);

No need to get too clever (especially since you got it wrong) about the sizeof argument, and no need to cast malloc()'s return value.

Community
  • 1
  • 1
unwind
  • 391,730
  • 64
  • 469
  • 606