Mac*_*htl 11 c++ function call
鉴于示例代码:
void func( char arg)
{
char a[2];
char b[3];
char c[6];
char d[5];
char e[8];
char f[13];
std::cout << (int)&arg << std::endl;
std::cout << (int)&a << std::endl;
std::cout << (int)&b << std::endl;
std::cout << (int)&c << std::endl;
std::cout << (int)&d << std::endl;
std::cout << (int)&e << std::endl;
std::cout << (int)&f << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
为什么每次通话都会得到类似的结果:
3734052
3734048
3734044
3734080
3734088
3734072
3734056
Run Code Online (Sandbox Code Playgroud)
每个地址都是偶数?为什么地址与代码中的变量不一样?
Zac*_*and 12
为什么地址与代码中的变量不一样?
结构中的第一个元素保证与结构本身位于同一位置(如果它们是一个元素的成员),但不保证其他元素按任何顺序排列.编译器将通过适当的顺序对它们进行排序,以允许它使用最少的空间.对于局部变量,它们位于内存中完全取决于编译器.它们都可能位于同一区域(可能因为它会利用局部性),或者它们可能遍布地图(如果你有一个糟糕的编译器).
每个地址都是偶数?
它将它们放在字边界上.这使得内存访问速度比没有放在字边界时更快.例如,如果a要放在一个字的最后一个字节上,而另一个字的第一个字节放在另一个字的最后一个字节上:
| WORD 1 | WORD 2 |
|--------|--------|--------|--------|--------|--------|--------|--------|
| a[0] | a[1] |
Run Code Online (Sandbox Code Playgroud)
然后访问a[0]然后a[1]需要将2个字加载到缓存中(每个缓存未命中).通过沿着单词边界放置:
| WORD 1 |
|--------|--------|--------|--------|
| a[0] | a[1] |
Run Code Online (Sandbox Code Playgroud)
高速缓存未命中a[0]将导致两者a[0]同时a[1]加载(减少不必要的存储器带宽).这利用了地方性原则.虽然语言当然不需要它,但它是由编译器完成的非常常见的优化(除非您使用预处理器指令来防止它).
在您的示例中(按顺序显示):
3734044 b[0]
3734045 b[1]
3734046 b[2]
3734047 -----
3734048 a[0]
3734049 a[1]
3734050 -----
3734051 -----
3734052 arg
3734053 -----
3734054 -----
3734055 -----
3734056 f[0]
3734057 f[1]
3734058 f[2]
3734059 f[3]
3734060 f[4]
3734061 f[5]
3734062 f[6]
3734063 f[7]
3734064 f[8]
3734065 f[9]
3734066 f[10]
3734067 f[11]
3734068 f[12]
3734069 -----
3734070 -----
3734071 -----
3734072 e[0]
3734073 e[1]
3734074 e[2]
3734075 e[3]
3734076 e[4]
3734077 e[5]
3734078 e[6]
3734079 e[7]
3734080 c[0]
3734081 c[1]
3734082 c[2]
3734083 c[3]
3734084 c[4]
3734085 c[5]
3734086 -----
3734087 -----
3734088 d[0]
3734089 d[1]
3734090 d[2]
3734091 d[3]
3734092 d[4]
Run Code Online (Sandbox Code Playgroud)
假设没有其他数据被分配给这些漏洞,那么看起来您对编译器的任何设置都会确保所有数组都从字边界开始.它不是,它是在阵列之间增加空间(如你可以看到有之间没有空格e和c),而第一个元素必须是一个字边界上.这是特定于实现的,并不是标准所要求的.