PGOnTheGo
PGOnTheGo

Reputation: 805

copying values from a integer array to integer struct

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

Answers (2)

user2088639
user2088639

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

Adam H. Peterson
Adam H. Peterson

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

Related Questions