Reputation: 805
I have an integer array:
int num[20] = {1,1,5,5,1,1,5,9,2,2,6,1,1,2,5,5,1,3,6,2};
I want to copy the elements num
into the following struct:
struct tuple
{
int p1;
int p2;
int p3;
int p4;
};
I am doing the following:
struct tuple *arr;
memcpy(&arr,&num,sizeof(num));
This does not seem to work, since I am encountering a segmentation fault later on in the code. When I try to print the size:
printf("size of arr: %lu, size of arr[0]: %lu \n", sizeof(arr), sizeof(arr[0]));
I get the following:
size of arr: 8, size of arr[0]: 16
which is wrong, since the values should read:
size of arr: 80, size of arr[0]: 16
Therefore when I try to print, it seg faults:
for (i=0;i<sizeof(arr)/sizeof(arr[0]);++i)
printf("%d,%d,%d,%d\n", arr[i].p1,arr[i].p2, arr[i].p3, arr[i].p4);
Can someone assist me as to where I might be going wrong?
Upvotes: 1
Views: 155
Reputation:
Several points to make here. Firstly:
struct tuple *arr;
memcpy(&arr,&num,sizeof(num));
arr
is a pointer to a struct tuple
; it is not a struct tuple
, and it's size is the pointer size on your system (which is probably 8 bytes), not the same size as a struct tuple
. When you do the memcpy
, it's copying over the pointer to struct tuple
, not a struct tuple
instance.
Secondly, if you meant to copy to a struct tuple
like this:
struct tuple aTuple;
memcpy(&aTuple,&num,sizeof(num));
Then you would have an actual instance of a struct tuple
rather than just a pointer, and the memcpy would copy to that memory. But this would still be wrong because:
1) The size of the array is much larger than the size of struct tuple
, and
2) Structures are not guaranteed to have all their fields adjacent in memory. There can be padding between p1
and p2
, etc., so the structure and the array would be arranged in memory differently and not directly copyable.
Incidentally, this would work for memcpy to a struct tuple
:
struct tuple aTuple;
aTuple.p1 = aTuple.p2 = aTuple.p3 = aTuple.p4 = 42;
struct tuple anotherTuple;
memcpy(&anotherTuple,&aTuple,sizeof(struct tuple));
I post that only as an example of correct usage.
EDIT:
Another thing, regarding this:
printf("size of arr: %lu, size of arr[0]: %lu \n", sizeof(arr), sizeof(arr[0]));
Did you pass num
to another function, as parameter arr
? In that case the arr
is also a pointer, whose size is 8 rather than 80. When you pass an array to a function, it is passed as a pointer.
Upvotes: 3
Reputation: 4591
Try replacing struct tuple *arr;
with struct tuple arr[5];
or perhaps struct tuple arr[sizeof(num)/sizeof(struct tuple)];
. When you declare arr
as a pointer, it doesn't allocate any space for the array it's pointing to. When you declare it as an array, it will decay to a pointer in the memcpy
call and blit the int array over top of the stack-(or static-)allocated struct array.
Alternatively, you could initialize arr
with a call to malloc(sizeof(num))
, but be sure to match such a call with a call to free()
.
Also, as pointed out by comments, you need to pass arr
and num
rather than &arr
and &num
. You want to copy the data, not the pointers (although it may be that &num
is equivalent to num
as a pointer, in this case).
Upvotes: 0