0

Here is the code ,

float *p = malloc(3*sizeof(float))

p[0] = 12.33;
p[1] = 13.66;
p[2] = 10.2;

Instead of initializing the array elements one by one, i tried this

p = {12.33,13.66,10.2};

but it is showing error, why wouldn't I able to do this ? P.S:Mind any silly mistakes.

  • Initializer lists can only be used when initializing variables, not in assignments. You could use `memcpy()` with a [compound literal](https://en.cppreference.com/w/c/language/compound_literal) – Barmar Mar 22 '23 at 15:06
  • @Barmar , Can you be more elaborate? – Vasanthan S R Mar 22 '23 at 15:07
  • 1
    See https://stackoverflow.com/questions/75187623/initializing-a-dynamically-allocated-array-with-a-compound-literal/75187680#75187680 for an example – Barmar Mar 22 '23 at 15:08
  • The simplest way is just to create a static array with the appropriate data, then `memcpy` it into the dynamic one. The compound literal approach reduces to basically the same thing at runtime, and is IMHO more confusing for the programmer. – Nate Eldredge Mar 22 '23 at 15:49

2 Answers2

2

You can use compound literal for that. Here is handy macro:

#define INIT(array, type, nelem, ...) memcpy(array, (type []){__VA_ARGS__}, nelem * sizeof(type))

Example usage:

float *foo(void)
{
    float *f = malloc(5 * sizeof(*f));
    INIT(f, float, 5, 1.0f, 2.0f, 3.0f, 4.0f, 5.0f);
    return f;
}

Optimizing compilers will get rid of the compound literal and malloc call generating some optimized code:

foo:
        push    rax
        mov     edi, 20
        call    malloc
        movabs  rdx, 4611686019492741120
        movabs  rcx, 4647714816524288000
        mov     QWORD PTR [rax], rdx
        mov     QWORD PTR [rax+8], rcx
        mov     DWORD PTR [rax+16], 0x40a00000
        pop     rdx
        ret
0___________
  • 60,014
  • 4
  • 34
  • 74
1

Keeping it very simple: just create a static (non-dynamic) array initialized with the appropriate data, then use memcpy to copy it into the new dynamic array.

void foo(void) {
    static const float initial_data[] = {12.33,13.66,10.2};
    float *p = malloc(3 * sizeof(float));
    memcpy(p, initial_data, 3*sizeof(float));
    // ...
}

This ends up doing more or less the same thing at runtime as the approaches with compound literals, and in my opinion the compound literals and variadic macro magic just make the code harder to understand.

Nate Eldredge
  • 48,811
  • 6
  • 54
  • 82