3

I'm trying to assign an array to one of the fields of a typedef struct and I can't find a way to do it practically.

I've searched for this problem but all I seem to find is answers for char * arrays which is not what I'm looking for, I'm just trying to assign an array to an int array, and looking for a practical way for the code below to work without having to initialize all the variables in the struct (they will be initialized later, but I just want to set the array variable):

typedef struct {
    int array[5];
    int number;
} Rot;

Rot RA;

void config()
{
    RA.array = {1, 2, 3, 4, 5}; //This returns an "expected expression before "{"" error
    int arr[5];
    int i;
    for (i = 0; i < 5; i++)
    {
        arr[i] = i + 1;
    }
    RA.array = arr; //I understand why this fails, but I need to do this in a practical way
}

Please assume that config is called later and the struct and RA are all accessible to it.

2
  • 2
    You can't assign arrays using a single assignment. Acceptable ways are either a loop that assigns one element at a time (e.g. for (int i = 0; i < 5; ++i) RA.array[i] = arr[i];) or copying memory (e.g. memcpy(RA.array, arr, 5*sizeof(int)) where memcpy() is declared in standard header <string.h>). Commented Jun 4, 2019 at 9:39
  • Curvy braces are used for initialization lists, so to use them you need to initialize something with them. But then there is a problem of "array" being a pointer to an allocated block of 5 ints, little more. Thus if you just do array = new int[] {1,2,3,4,5} you make it point to a different block of memory, which may have diffetent lifespan from your structure, thus you have to memcpy or re-assign each element in a for loop. Commented Jun 4, 2019 at 10:04

4 Answers 4

4

RA.array = {1, 2, 3, 4, 5};

memcpy(RA.array, (int[]){1, 2, 3, 4, 5}, sizeof RA.array);

RA.array = arr;

memcpy(RA.array, arr, sizeof arr); // better: sizeof RA.array
Sign up to request clarification or add additional context in comments.

Comments

2

You can use memcpy as shown in another answer. Or alternatively, copy the whole struct and not just the array, using a temporary variable in the form of a compound literal:

RA = (Rot) { {1, 2, 3, 4, 5}, 0 };

This is possible because while C doesn't allow run-time assignment of arrays, it does allow it of structs.

Comments

1

You can use memcpy as shown in another answer, or copy the whole struct as shown in another answer (although your question states that you just want to set the array, not the remainder of the struct).

Another option is to embed just the array into another struct:

typedef struct {
    int elem[5];
} RotArr;

typedef struct {
    RotArr arr;
    int number;
} Rot;

Then you can access element i of the array in Rot RA as RA.arr.elem[i]. Also, you can assign values to a whole RotArr object. The remainder of your code could look something like this:

Rot RA;

void config(void)
{
    RA.arr = (RotArr){{1, 2, 3, 4, 5}};
    RotArr arr;
    int i;
    for (i = 0; i < 5; i++)
    {
        arr.elem[i] = i + 1;
    }
    RA.arr = arr;
}

Note that (RotArr){{1, 2, 3, 4, 5}} is a compound literal value of RotArr type. It could also be written as (RotArr){ .elem = {1, 2, 3, 4, 5} } or (RotArr){ .elem = { [0] = 1, [1] = 2, [2] = 3, [3] = 4, [4] = 5 } } to be absolutely clear which parts of the compound literal are being set explicitly (any remaining parts will be set to 0), but since it only has a single member, these forms of the compound literal value are a bit over-the-top.

Comments

1

The following works according to C syntax. Not sure this is what you wanted.

#include <string.h>
#include <stdio.h>

typedef struct {
    int array[5];
    int number;
} Rot;

Rot RA = {{1,2,3,4,5}};

void main()
{
    RA = (Rot) {{5, 6, 7, 8, 9}};
    int arr[5];
    int i;
    for (i = 0; i < 5; i++)
    {
        arr[i] = i + 1;
    }

    memmove(RA.array, arr, sizeof(RA.array));
    // OR
    
    int l = sizeof(arr)/sizeof(arr[0]);
    for(int i =0 ; i < l ; ++i) {
        *(RA.array + i) = *(arr + i);
        printf("%d\n",RA.array[i]);
    }
}

Moreover, use memmove since that allows memory overlap.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.