Search code examples
cpointersdeep-copy

C copy static array into a structure


I have a structure that looks like this:

typedef struct object {
  entry **entries;
} object;

typedef struct entry {
  int value;
} entry;

Somewhere in my code i have a static array of entries(initialized with some random data);

entry entries[][] = {... (doesn't matter)...};

How can i copy these entries into an object? I need something like this:

object obj;
obj.entries = entries;

Edit: I do not want to copy every element in a 'for' loop.

After suggestions:

Ok. I have:

entry entries[initial_height][initial_width];
....initialize entries...
object obj;
int i;
obj.entries = (entry**) malloc(initial_height * sizeof(entry*));

for (i = 0 ; i < initial_height; i++) {
    obj.entries[i] = (entry*) malloc(initial_width * sizeof(entry));
}

memcpy(obj.entries, entries, sizeof(entry) * initial_height * initial_width);

printf("%d\n", entries[0][0].value);
printf("%d\n", obj.entries[0][0].value);

And i'm getting a segmentation fault(the first print works). What am i still doing wrong?


Solution

  • Your problem lies with memcpy. The basic idea in memcpy is that it starts from the 2 pointers specified in the parameters of memcpy and copies the number of bytes specified by you.

    In your case you follow 2 steps::

    1) You declare an array of pointers of entry.

    2) You declare arrays of entry and save the pointer returned by malloc into the array of pointers declared in (1).

    You should also take into consideration that your every array declared in step (2) could be declared anywhere in the memory not necessarily contiguously.

    So, when you call memcpy(obj.entries[i], entries[i], sizeof(entry) * initial_width); you start copying bytes of entries to the array of pointers obj.entries[i] which is only of size initial_height * sizeof(entry*), so anything you copied beyond this limit, is corrupting the memory, which is the reason you get a segmentation fault. (Since you also over-write the bytes storing the location of dynamically declared arrays of entry)

    A possible approach to do it would be as follows ::

    for(int i = 0; i < initial_height; i++) {
        memcpy(obj.enteries[i], entries[i], sizeof(entry) * initial_width);
    }
    

    You will anyway have to use 1 for loop if you want to create your 2D array dynamically. In case you don't want this either, you will have to declare a static array!