1

I have dynamically allocated a pointer to an integer - which is intended to be an array - and I want to fill this array with a specific set of numbers.

int * myArr= (int*)malloc(SIZE_OF_ARRAY * sizeof(int));

if (myArr == NULL) {
    return EXIT_FAILURE;
}

*myArr = {452,35,351,53,66};

I tried other options as well:

myArr[] = {452,35,351,53,66};
myArr[5] = {452,35,351,53,66};

but the issue is the same.

  • One by one. Or `memcpy` from another array (probably pointless in your case). – Eugene Sh. Sep 30 '20 at 18:46
  • the function you want is memset , this will get you going https://stackoverflow.com/questions/7202411/why-does-memsetarr-1-sizeofarr-sizeofint-not-clear-an-integer-array-t – newbie Sep 30 '20 at 18:49
  • As an aside, because this is `C`, and not `C++`, this: `int * myArr= (int*)malloc(SIZE_OF_ARRAY * sizeof(int));` can ( [and should be](https://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) ) reduced to `int * myArr= malloc(SIZE_OF_ARRAY * sizeof(*myArr));` (Referring to the cast mainly, but if interested in why I also changed argument of `sizeof`, [read this](https://softwareengineering.stackexchange.com/questions/201104/sizeof-style-sizeoftype-or-sizeof-variable)). – ryyker Sep 30 '20 at 19:00
  • Do you really _need_ this to be dynamically allocated, or could it be simply a pointer type, set to point to an initializer block? If the later, then `int *p = &initializer_block;` will work without the extra cost of dynamic allocation. – ryyker Sep 30 '20 at 21:49

2 Answers2

3

You can use memcpy() from the array that has the initial values.

static const int initial_values[] = {452, 35, 351, 52, 66};
memcpy(myArr, initial_values, sizeof(initial_values));

Arrays can't be assigned directly to each other, because when they're used in R-value context they decay to a pointer to the first element.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • Thank you! While this solution works, I'm wondering why it's not possible to directly assign an array of integers to a previously dynamically allocated pointer to an int array? – Axel Brugger Sep 30 '20 at 19:01
  • Because arrays aren't things you can assign. – Barmar Sep 30 '20 at 19:02
  • An array decays to a pointer to its first element in an r-value context. – Barmar Sep 30 '20 at 19:03
  • This has a double overhead though (if used in a function). 1) `inital_values` is allocated on stack 2) It's initializer is allocated statically 3) The initialization is happening in the runtime – Eugene Sh. Sep 30 '20 at 19:24
  • You can make it static to avoid all that overhead if it's a problem. – Barmar Sep 30 '20 at 19:25
1

Addressing your question in comments under first answer: " why it's not possible to directly assign an array of integers to a previously dynamically allocated pointer to an int array", It is also possible to use this approach (which does not use dynamically allocated memory, but does use a pointer type set to the address of array:

int initial_values[] = {452,35,351,53,66};
int *pMyArray = &initial_values[0]; //sets pointer to address of array[0]

Now you have a pointer type pointing to valid memory containing the same content without memory allocation, and without the need to free allocated memory.

( This exact method is also described here ).

Edit To answer question in comments "What's the point of this?...
... If you don't need it to be dynamic, you can just use initial_values as a pointer."

The short answer is to provide compatibility with certain function prototypes, while not requiring dynamic allocation. The pointer type will compile and run, the array type will not. i.e. even though initial_values points to the address of the array, &initial_values does not make it compatible to int **a, while &pMyArray is compatible.

The following illustration uses s_test test and s_test *p as types as replacements to initial_values and pMyArray:

typedef struct {
    int iVal;
    double dVal;
    char sVal[10]
}s_test;
#define SIZE 5
void func(s_test **t, size_t size)
{ 
    const char *new[10] = {"new1","new2","new3","new4","new5"};
    for(int i=0;i<size;i++)
   {
        (*t)[i].iVal *=10;
        (*t)[i].dVal *=10.0;
        strcpy((*t)[i].sVal, new[i]);
   }
}
int main(void)
{
    s_test test[SIZE] = {{1, 1.0, "string1"},
                     {2, 2.0, "string2"},
                     {3, 3.0, "string3"},
                     {4, 4.0, "string4"},
                     {5, 5.0, "string5"}};
    
    s_test *p = &test[0];

    func(&p, SIZE); //this works using pointer to pointer
    func(&test, SIZE);//run-time error, general protection
    
    return 0;   
}
ryyker
  • 22,849
  • 3
  • 43
  • 87
  • What's the point of this? If you don't need it to be dynamic, you can just use `initial_values` as a pointer. – Barmar Sep 30 '20 at 19:26
  • @Barmer - Which begs the question, why allocate memory in the first place then? But good point, I have used this method to initialize pointer variables that I would subsequently pass as function arguments that required a `type **` parameter, i.e. to modify struct contents, initialized by an existing array of struct. And, I suppose it would have been fine just to use the array of struct in the same way, as its name is essentially a pointer to its memory address. But you are right, other than _it works_ I cannot assert anything more :) – ryyker Sep 30 '20 at 19:50
  • I presume the dynamic allocation is because the size needs to be dynamic, or they need to use `realloc()` to resize it, or the array has to outlive the lifetime of local variables -- all the usual reasons for using `malloc()`. All he wants to do is initialize the contents when allocating. – Barmar Sep 30 '20 at 19:56
  • @Barmer - Yes, reason for dynamic allocation is an assumption, but not important to your question. I ran some tests to remind myself why I used this before (see last comment.) See edit to answer your question _Whats the point_.... I am interested in your comment after seeing it. – ryyker Sep 30 '20 at 20:40