19

How do I initialize a dynamic array allocated with malloc? Can I do this:

int *p;
p = malloc(3 * sizeof(*p));
p = {0, 1, 2};

...

free(p);

Or do I need to do something like this:

int *p, x;
p = malloc(3 * sizeof(*p));
for (x = 0; x < 3; x++)
    p[x] = 0;

...

free(p);

Or is there a better way to do it?

10
  • 1
    Did you mean p[x] = x; instead of p[x] = 0;? Commented Jul 30, 2013 at 3:06
  • 1
    The second method is the correct way. The first one gets a compiler error, doesn't it? Commented Jul 30, 2013 at 3:06
  • fydo.net/gamedev/dynamic-arrays shows how to use dynamic arrays. in fact its a very popular link and you can find it with any major search engine... Commented Jul 30, 2013 at 3:06
  • I think the more tedious way is the only way to do it. I tried the first one and it doesn't compile (After commenting the '...') No many shortcuts in 'C' I guess.ac Commented Jul 30, 2013 at 3:09
  • 1
    I have heard that some programmers use the memset() function for something like this. Commented Jul 30, 2013 at 3:10

4 Answers 4

28

You need to allocate a block of memory and use it as an array as:

int *arr = malloc (sizeof (int) * n); /* n is the length of the array */
int i;

for (i=0; i<n; i++)
{
  arr[i] = 0;
}

If you need to initialize the array with zeros you can also use the memset function from C standard library (declared in string.h).

memset (arr, 0, sizeof (int) * n);

Here 0 is the constant with which every locatoin of the array will be set. Note that the last argument is the number of bytes to be set the the constant. Because each location of the array stores an integer therefore we need to pass the total number of bytes as this parameter.

Also if you want to clear the array to zeros, then you may want to use calloc instead of malloc. calloc will return the memory block after setting the allocated byte locations to zero.

After you have finished, free the memory block free (arr).

EDIT1

Note that if you want to assign a particular integer in locations of an integer array using memset then it will be a problem. This is because memset will interpret the array as a byte array and assign the byte you have given, to every byte of the array. So if you want to store say 11243 in each location then it will not be possible.

EDIT2

Also note why every time setting an int array to 0 with memset may not work: Why does "memset(arr, -1, sizeof(arr)/sizeof(int))" not clear an integer array to -1? as pointed out by @Shafik Yaghmour

Sign up to request clarification or add additional context in comments.

Comments

24

Instead of using

int * p;
p = {1,2,3};

we can use

int * p;
p =(int[3]){1,2,3};

2 Comments

This is exactly what I was looking for! Super useful if each individual element has its own value what cannot be computed in any way, so you end-up writing initialization for each element individually. One question: is it part of any C standard, or is it compiler specific?
This is not a drop-in replacement for a malloc-ed array! The compound literal you're using to initialize p has automatic storage duration. It will be freed automatically at the end of the block, and calling free on it manually is undefined behavior. You can't use this to allocate an array you're going to return, or to allocate anything that has to persist beyond the current block.
8

You cannot use the syntax you have suggested. If you have a C99 compiler, though, you can do this:

int *p;

p = malloc(3 * sizeof p[0]);
memcpy(p, (int []){ 0, 1, 2 }, 3 * sizeof p[0]);

If your compiler does not support C99 compound literals, you need to use a named template to copy from:

int *p;

p = malloc(3 * sizeof p[0]);
{
    static const int p_init[] = { 0, 1, 2 };
    memcpy(p, p_init, 3 * sizeof p[0]);
}

Comments

3

p = {1,2,3} is wrong.

You can never use this:

int * p;
p = {1,2,3};

loop is right

int *p,i;
p = malloc(3*sizeof(int));
for(i = 0; i<3; ++i)
    p[i] = i;

Comments