1

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?

8
  • 2
    You can't memcpy to an uninitialized pointer. Commented May 31, 2013 at 22:21
  • 3
    Also, arr is a pointer, that that is eight bytes large is not surprising. Commented May 31, 2013 at 22:22
  • 5
    @chris The argument to memcpy is the address of the pointer. Not sure whether that's worse or better than an uninitialised pointer. Commented May 31, 2013 at 22:24
  • 3
    You were really wanting to do memcpy(arr,num,sizeof(num)); vs. memcpy(&arr,&num,sizeof(num)); But the are many other problems than this. Need new approach. Commented May 31, 2013 at 22:26
  • Strange is that you need such a copying at all. What are you trying to achieve? The chances are high that there is a more appropriate way to do it. Commented May 31, 2013 at 22:27

2 Answers 2

3

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.

Sign up to request clarification or add additional context in comments.

1 Comment

It looks to me like arr is his struct tuple *, which means it's a pointer to tuples and therefore the sizeof() quotient trick won't work. If arr were struct tuple[5], though, it would be fine (provided, of course, it weren't passed through a function and decayed to a pointer, as you mention).
0

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).

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.