鉴于以下设计的示例代码:
struct abc
{
int x[5];
int y[5];
};
void main()
{
struct abc test;
test.y[0] = 10;
printf("%n", test.x[5]);
}
Run Code Online (Sandbox Code Playgroud)
该计划的输出是10.
虽然不是最好的编程实践,但这确实有效.但是,这是编译器和平台的工件,还是这个合法代码?(即由C标准定义?)
即使结果不能保证为10,有没有一个例子,这将是"非法的"(即写入内存我不"拥有")?
Dan*_*ego 12
不,这不合法,也不保证有效.编译器可以在结构中添加填充,以帮助对齐,具体取决于体系结构等.
编辑:总结这些评论中的一些内容并澄清......
我确实相信你"拥有"那里的记忆,因为正如edA-qa mort-ora-y指出的那样,结构的memcpy()需要/有望起作用.虽然这是特别保证的,但我不确定.
话虽如此,未定义的行为是不惜一切代价避免的.具有未定义行为的程序可以在相隔五秒钟的相同代码的两次单独运行之间进行更改.它可能会导致程序中的细微内存损坏,段错误或运行正常,但没有理由使用依赖于未定义行为的代码.
这是未定义的行为 - 在这种情况下你是(非)幸运的.更进一步(除了上面提到的填充问题),存在可维护性问题 - 它非常脆弱 - 如果有人在其他方面粘贴其他内容会怎么样.我敢肯定这是一个人为的例子,但建议是 - 不要这样做.
编辑:正如其他人指出的那样,这是不合法的,因为它会导致未定义的行为。我已从我的答案中删除了这句话。
这有可能导致未定义的行为。您已在 struct abc 中分配了 10 个 int 长的内存块,因此索引到第 5(第 6)项将带您到 y[0],正如您在该特定情况中所指出的那样。
当 C 编译器以您不期望的方式打包结构时,您可能会遇到问题。这称为数据打包或位对齐。当计算机想要从数据结构访问内存时,它将尝试以整个结构的统一块的形式进行访问。让我们举个例子:
struct abc {
int a;
char b;
int c;
};
Run Code Online (Sandbox Code Playgroud)
您预计该结构的大小是多少?int 为 32 位,char 为 8 位,因此总大小应为 32 + 8 + 32 = 72 位。然而,你会发现在很多系统上,这个结构体的大小实际上是96位。原因是 char b 在末尾进行了位打包,并附加了 24 位,以维持变量之间的标准偏移量。
当您在两个不同的位置声明一个结构时,这可能会非常令人困惑,并且由于编译时选项或配置的原因,一个位置会被位打包,而另一个则不会。
查找位打包和数据对齐或位对齐以获取更多信息。
| 归档时间: |
|
| 查看次数: |
298 次 |
| 最近记录: |