[英]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.
我不确定我做错了什么。
There are two problems with your copying mechanism: 复制机制有两个问题:
sizeof(Info)
is 5. That's definitely not the case. sizeof(Info)
是5.那绝对不是这样的。 strncpy
, which is for strings. strncpy
,这是用于字符串的。 Info
is not a string, so you need to use memcpy
. Info
不是字符串,因此您需要使用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 . name[5]
不足以容纳"Casey"
,因为一旦你考虑了null终止符,就会有6个字符。
There's a few things: 有几件事:
char name[5]
can't hold "Casey"
, the terminator won't fit. char name[5]
不能容纳"Casey"
,终结符将不适合。 This causes undefined behavior. &i
as if that was the pointer to a string, when in fact it points at a struct
whose first field is an int
. &i
,就好像那是指向字符串的指针,而实际上它指向一个struct
,其第一场是int
。 This won't work reliably. 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. 首先,考虑到“Casey”必须为空终止,
info
的name
字段太短。
The observation you made is due to another problem. 你做的观察是由于另一个问题。 The address of
j
will not be aligned with its name
field. j
的地址不会与其name
字段对齐。 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. 在那个地方仍然存在一个
int age
,并且很可能name
字段在4个字节之后开始,但这是由编译器自行决定的。
As for recovering age
, that would not work because it was never stored to the buffer. 至于恢复
age
,这是行不通的,因为它从未存储到缓冲区。
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. 假设
buffer
足够大,可以使用memcpy(buffer, &i, sizeof(Info))
来存储,前两个参数切换为重建。 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. 在这里使用
sizeof
会有所帮助,因为这样你就可以向编译器询问结构Info
在内存中布局这个结构的方式有多大。
You do not need to use memcpy() to copy Info
variables. 您不需要使用memcpy()来复制
Info
变量。 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. 您可以这样做,因为
Info
不包含指针成员变量,因此在使用赋值运算符时您将获得深层复制。 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. 当然,正如其他人所指出的那样,你应该使
Info::name
足够大,以容纳你打算存储在其中的名称,包括'\\0'
字符串终止符。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.