18

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?

  • 1
    Did you mean `p[x] = x;` instead of `p[x] = 0;`? – Mysticial Jul 30 '13 at 03:06
  • 1
    The second method is the correct way. The first one gets a compiler error, doesn't it? – Barmar Jul 30 '13 at 03:06
  • http://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... – franklin Jul 30 '13 at 03:06
  • Why are you using `malloc` in the first place – Ed Heal Jul 30 '13 at 03:14
  • 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 – user763410 Jul 30 '13 at 03:09
  • 1
    I have heard that some programmers use the memset() function for something like this. –  Jul 30 '13 at 03:10
  • @JustinChadwell You can not use `memset` for this: http://stackoverflow.com/questions/7202411/memset-integer-array?rq=1 – Shafik Yaghmour Jul 30 '13 at 03:24
  • @ShafikYaghmour: If someone wants to clear the array using 0, `memset` is perfectly fine. – phoxis Jul 30 '13 at 03:41
  • @phoxis Since we don't have any details on the system being used, we don't really know it will work properly as explained in this answer: http://stackoverflow.com/a/7202857 although in most settings you are probably ok – Shafik Yaghmour Jul 30 '13 at 03:45
  • @ShafikYaghmour: Those are valid causes, definitely not necessarily the number representation is two's compliment and integers may have padding also. – phoxis Jul 30 '13 at 03:52

4 Answers4

27

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

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
phoxis
  • 60,131
  • 14
  • 81
  • 117
23

Instead of using

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

we can use

int * p;
p =(int[3]){1,2,3};
EnterKEY
  • 1,180
  • 3
  • 11
  • 25
  • 2
    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? – Ignas2526 Aug 11 '13 at 19:04
  • 15
    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. – user2357112 Jul 27 '16 at 19:27
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]);
}
caf
  • 233,326
  • 40
  • 323
  • 462
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;
Lidong Guo
  • 2,817
  • 2
  • 19
  • 31