Reputation: 776
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?
Upvotes: 1
Views: 1285
Reputation: 2172
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!
Upvotes: 1
Reputation: 3080
It would be better to allocate and copy at the same place:
for (i = 0 ; i < initial_height; i++) {
obj.entries[i] = (entry*) malloc(initial_width * sizeof(entry));
memcpy(obj.entries[i], entries[i], sizeof(entry) * initial_width);
}
Upvotes: 0