gpt4 book ai didi

c - 我可以假设结构字段按顺序放置并且没有填充吗?

转载 作者:太空宇宙 更新时间:2023-11-04 06:56:30 25 4
gpt4 key购买 nike

坦率地说,这样的代码是有效的还是会调用未定义的行为?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct two_values
{
int some;
char value;
};

int main(void) {
int some = 5;
char value = 'a';
unsigned char *data = malloc(sizeof(struct two_values));
memcpy(data, &some, sizeof(int));
memcpy(data+sizeof(int), &value, sizeof(char));
struct two_values dest;
memcpy(&dest, data, sizeof(struct two_values));
printf("some = %d, value = %c\n", dest.some, dest.value);
return 0;
}

http://ideone.com/4JbrP9

我能否将两个 struct 字段的二进制表示放在一起并将其重新解释为整个 struct

最佳答案

你最好不要在你的代码中干扰内部编译器的行为,因为它会导致你产生不正确的代码和未定义的行为。你可以切换编译器,或者只是更新你最喜欢的版本,然后遇到麻烦。

解决您所展示的具有两个变量并将它们正确存储在 struct 字段中的最佳方法是正确使用 C 提供的类型,并使用指向正确类型的指针类型。如果你使用

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct two_values
{
int some;
char value;
};

int main(void) {
int some = 5;
char value = 'a';
/* next instead of unsigned char *data = malloc(sizeof(struct two_values)); */
struct two_values *data = malloc(sizeof(struct two_values));
/* next instead of memcpy(data, &some, sizeof(int)); */
data->some = some;
/* next instead of memcpy(data+sizeof(int), &value, sizeof(char)); */
data->value = value;
struct two_values dest;
/* next instead of memcpy(&dest, data, sizeof(struct two_values)); */
dest = *data;

printf("some = %d, value = %c\n", dest.some, dest.value);
return 0;
}

您将避免所有编译器对齐问题。 总是可以使用语言运算符&(地址)和*(指向)或->(struct 指向的字段)。

无论如何,如果您更喜欢memcpy 方法(不知道为什么,但无论如何您都在路上),您可以替代:

data->some = some;
...
data->value = value;
...
dest = *data;

通过

memcpy(&data->some, &some, sizeof data->some);
...
memcpy(&data->value, &value, sizeof data->value);
...
memcpy(&dest, data, sizeof dest);

这将在内部采用编译器可以自行进行的对齐。

所有编译器都定义了一些 pragma 或关键字来控制对齐。这也是不可移植的,因为您可以切换编译器并解决必须更改表达方式的问题。 C11 有一些标准的方法来控制压缩结构并且在编译器中不使用对齐。这主要是在您必须序列化某些结构并且不想处理其上的漏洞时完成的。查看 C11 规范。

序列化结构并不能完全通过打包来解决,因为通常你必须处理整数、浮点或字符数据的序列化表示(它们可以与编译器使用的内部表示一致也可以不一致)所以你再次面临与编译器无关的问题,在外部使用数据的内部表示之前必须三思而后行。

无论如何,我的建议是,永远不要相信编译器如何在内部存储数据。

关于c - 我可以假设结构字段按顺序放置并且没有填充吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43734082/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com