user1377000
user1377000

Reputation: 1483

Cast struct pointer to char* and copy

I have the following code

struct Info { int age; char name[5]; }
char buffer[20];
Info i;
i.age = 10;
sprintf(i.name, "Case");
strncpy(buffer+5, (char*)&i, sizeof(Info));

Now I want to recover the record

Info j;
strncpy((char*)&j, buffer+5, sizeof(Info));
printf("%d %s", j.age, j.name);

However this prints empty string for name. I'm not sure what I am doing wrong.

Upvotes: 3

Views: 6024

Answers (4)

Nikos C.
Nikos C.

Reputation: 51930

You do not need to use memcpy() to copy Info variables. You can just use the assignment operator:

Info j;
j = i;
printf("%d %s", j.age, j.name);

You can do that because Info does not contain pointer member variables, and therefore you'll get a deep copy when using the assignment operator. The same will happen if you just use the default copy constructor:

Info j(i);

or:

Info j = i;

Of course as pointed out by others, you should make Info::name large enough to hold the names you intent to store in it including the '\0' string terminator.

Upvotes: 0

s.bandara
s.bandara

Reputation: 5664

There are several issues with the code you posted. First, the name field of info is too short considering that "Casey" must be null terminated.

The observation you made is due to another problem. The address of j will not be aligned with its name field. There is still an int age in that place, and most likely the name field starts 4 bytes later, but this is to the discretion of your compiler.

As for recovering age, that would not work because it was never stored to the buffer.

What could work is, assuming that buffer is large enough, to memcpy(buffer, &i, sizeof(Info)) to store, and the first two arguments switched to reconstruct. Using sizeof helps here because this way you are asking the compiler how large the structure Info is given its way of layouting this structure in memory.

Upvotes: 0

unwind
unwind

Reputation: 400159

There's a few things:

  • You're overflowing the buffer, char name[5] can't hold "Casey", the terminator won't fit. This causes undefined behavior.
  • You're copying from &i as if that was the pointer to a string, when in fact it points at a struct whose first field is an int. This won't work reliably.

Upvotes: 4

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272822

There are two problems with your copying mechanism:

  1. You're assuming that sizeof(Info) is 5. That's definitely not the case.
  2. You're using strncpy, which is for strings. Info is not a string, so you need to use memcpy.

The following will work:

char buffer[sizeof(i)];
memcpy(buffer, &i, sizeof(i));

...

memcpy(&j, buffer, sizeof(j));

There's also another problem; name[5] is not big enough to hold "Casey", as that's 6 characters once you've accounted for the null terminator.

Upvotes: 6

Related Questions