Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/124.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 结构非常简单的allignment c/c++;_C++_Arrays_C - Fatal编程技术网

C++ 结构非常简单的allignment c/c++;

C++ 结构非常简单的allignment c/c++;,c++,arrays,c,C++,Arrays,C,鉴于我对allignment的理解正确,且鉴于我们有以下结构: struct someStruct{ short i1; short i2; short i3; }; 假设short是一个16位整数,有2个字节的对齐,并且我们使用的是32位机器和x86。我知道这个结构的大小将是6个字节。但是,我不明白的是,如果结构从奇数内存地址开始,会发生什么情况。它是否将填充添加到结构中,以便它以偶数形式“启动”?假设我们有一个这些结构的数组,那么只有第一个元素有这个额外的填充吗?此

鉴于我对allignment的理解正确,且鉴于我们有以下结构:

struct someStruct{
    short i1;
    short i2;
    short i3;
};

假设short是一个16位整数,有2个字节的对齐,并且我们使用的是32位机器和x86。我知道这个结构的大小将是6个字节。但是,我不明白的是,如果结构从奇数内存地址开始,会发生什么情况。它是否将填充添加到结构中,以便它以偶数形式“启动”?假设我们有一个这些结构的数组,那么只有第一个元素有这个额外的填充吗?此外,如果起始地址是偶数,但它在处理器字(即最小的可读内存块)的中间或在它的中间开始,这是否重要?在后两种情况下是否添加了填充?同样,这个填充是否只添加到这些结构数组的第一个元素?我的问题的答案是否意味着结构的大小是可变的,取决于它在内存中的创建位置?这是否意味着统一类型的结构数组的某些元素的字节大小与其他元素不同

<>我也问C和C++之间是否有这个主题的不同之处。如果可以提醒我,是否可以像处理基元类型的数组一样,使用指针算法遍历结构数组

澄清和更新:

到目前为止,我知道结构不能以奇数地址开始存储,但我仍然想知道,如果存储结构的地址从一个字的一半开始(,即最小的可读内存块)或从另一个开始,是否有任何区别。在如何将其对齐/存储/填充/装入阵列/其他数据结构等方面存在任何差异

为了使其更加简洁:

像这样的数据结构是否可能在数组中的内存字(,即最小的可读内存块)中间的内存地址中开始,或者不在数组中

说明(这是另一个最新更新,请参见):

在阅读了一些答案后,我截图维基百科以显示我的困惑来源:

结构本身的对齐方式为2,因此无法在奇数地址上一致地创建它。

由于结构的对齐方式为2,编译器将不会将其放置在奇数地址上,只有2的倍数,因此您(几乎)不必担心对齐。在某些情况下(不是您的示例),它可能会在成员之间添加填充,以确保每个成员都正确对齐,和/或它可能会在末尾添加填充,以便在将对象放入数组时,所有后续元素都会自动对齐,但我不知道编译器为什么会在结构的开头添加填充。普通编译时数组不需要在结构填充之上添加任何不可见的填充

<> C++中没有任何东西涉及单词,所以没关系。结构和基本体可以位于单词的开头、中间、结尾,也可以跨越多个单词。它们不会以任何方式相互影响。重要的是编译器会自动为您将其置于正确的对齐方式

在您的数组中,是的,2个结构的数组可能会稍微偏离单词大小

structs:       [i1  ][i2  ][i3  ][i1  ][i2  ][i3  ]
words:   [          ][          ][          ][          ]
bytes:   [ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ][ ]
这是完全正确的。CPU永远不会在一次操作中对整个结构工作,只能对单个原语工作,因此如果它试图访问第一个结构的
i3
成员,它只会加载第二个字并使用它关心的字节。您完全可以使用指针数学来迭代这个结构数组,就像任何原语数组一样,100%相同

我不知道C和C++在这个方面有什么不同。 假设short是一个16位整数,具有2字节对齐,并且 我们使用的是32位机器和x86。我知道 此结构将有6个字节

不一定。该实现可自行决定在任何或所有成员之后添加填充。实现通常基于对齐考虑做出这样的决策,但它们不受此约束,也不受任何特定公式的约束

结构的对齐要求必须至少与任何成员的最大对齐要求一样大,但这并不意味着很大,因为C(或C++)实现对标量类型的对齐要求有自己的选择,而且,因为可以自由选择骨料和活接头类型的更大对齐要求,而不是满足其构件对齐要求所必需的对齐要求。历史上,一些实现在各种情况下都是这样做的。因此,即使我们假设您的实现仅为对齐目的而添加填充,您的结构也可能大于6个字节

实现通常遵循已建立的应用程序二进制接口,该接口将指定数据对齐和布局规则,但这样做是达到目的的手段(二进制兼容性),而不是语言要求


但是,我不明白的是,如果结构从奇数内存地址开始,会发生什么情况

如果结构类型的对齐要求至少为2,那么它不会从奇数地址开始,除非您通过某种形式的指针欺骗来强制它。如果强制未对齐,则通过未对齐指针访问结构的行为未定义。在实践中,通常更可能的行为包括(i)它只是工作,(ii)它工作但访问速度变慢,(iii)访问导致发出运行时信号

它是否将填充添加到结构中,以便它以偶数形式“启动”

填充是该类型的特征,而不是实例,并且该类型的第一个字节永远不是填充字节。更确切地说,假设你让