C Array Bounds与邻近对象的错误

来自http://www.doc.ic.ac.uk/teaching/projects/Distinguished03/AndrewSuffield.pdf :

#include  struct x { char s[10]; int a[4]; }; void bang(struct x *d) { strcat(d->s, "!"); } int main(void) { struct xd; strcpy(ds, "012345678"); da[0] = 3; da[1] = 2; da[2] = 1; da[3] = 0; bang(&d); return a[0]; } 

在此示例中,struct x包含一个10字节的字符串,后面紧跟一个4整数数组。 d用9个字符的字符串初始化(由于尾随NULL占用10个字节)和4个整数。 bang()附加一个! 到字符串,使其成为“012345678!” 加上一个尾随的NULL。

字符串末尾的NULL字节将覆盖da [0]的第一个字节。 在big-endian主机上,这将无效,因为该字节已经为零。 在little-endian主机上,这会将da [0]的值更改为零

两个问题:

  1. s&a之间是否存在结构孔,因此上述论点不成立。 gcc给出返回值为3。
  2. 返回a [0]在我的系统(gcc)上不起作用。

  1. 这些领域之间很可能有填充。 在任何现代系统上都会有。 尝试将strcat传递给更长的字符串。
  2. return a[0]显然是一个错字。 它应该读取return da[0]
  1. 是的,在sa之间可能会有填充以对齐与int对齐。

  2. 你需要改变它以return da[0]; ,没有名为a变量。

还要意识到ds的字节在创建时不能保证初始化为0 ,并且使用它是未定义的行为。 所以strcat可以搜索一个NUL终结器而不是找到一个并进入你不拥有的内存并导致段错误。 在使用strcat之前,你应该首先使ds成为C字符串,

像这样:

 struct xd; ds[0] = 0;