@osmanthus
试试打印地址出来看看
-
一段代码在32位环境下的错误
-
@诟屍 我搞懂了, 不同的编译器会把
i
放在不同的地方,有些会把它放在数组a
后边
有些就会放在前边. -
64位如果放在
a
前边也不会出问题 因为在这样的情况肯定是先分配a
的空间 栈顶向下生长 然后再分配i
的 然而还要进行内存对齐(按八) 所以修改a[10]
并不会修改到i
只会修改i边界后边4个字节的内存 -
@osmanthus 在 一段代码在32位环境下的错误 中说:
@诟屍 我搞懂了, 不同的编译器会把
i
放在不同的地方,有些会把它放在数组a
后边
有些就会放在前边.为什么64位下会把
i
放在前面,32位下会把i
放在后面
试试变成全局变量int a[10], i; int main( void ) { for( i = 1; i <= 10; i++ ) a[i] = 0; return 0; }
@osmanthus 在 一段代码在32位环境下的错误 中说:
64位如果放在
a
前边也不会出问题 因为在这样的情况肯定是先分配a
的空间 栈顶向下生长 然后再分配i
的 然而还要进行内存对齐(按八) 所以修改a[10]
并不会修改到i
只会修改i边界后边4个字节的内存栈往上长还是往下长都没关系吧233
从你这段话,我看不出跟64位有什么关系
64位里只不过是指针/long因为变成了8位,所以指针/long要按8对齐,其他应该是不变的 -
这部分应该是第九章虚拟内存的内容吧
-
@hhzzxx 虚拟内存对用户应该是透明的吧
-
@诟屍 应该是具体映射到的硬件位置对用户不可见。我们看到的指针好像就是虚拟内存的地址(不太清楚)。
主要是想表达 栈区的内存分配规则应该是虚拟内存的相关内容。 -
@hzx__
a
和i
的相对位置应该不关虚拟内存事吧
现在就是不清楚为什么64位下,局部变量的话,会把i
挪到a
前面,全局变量的话又不会,32位也不会 -
@诟屍 嗯确实,想当然了。刚刚翻了一下第九章,讲的都是物理地址与虚拟内存之间的映射关系。第七章好像讲了加载时的具体操作,不过没找到栈区内存分配规则,7.5讲了bss区的。没细看orz
-
在 Practice Problem 3.48 (P288) 里有个这样的问题:
How does the rearranged ordering of the local variables in the protected code provide greater security against a buffer overrun attack?
然后我就想起了本贴,于是赶紧上 爆栈网 搜一搜,发现了解答:
The C standard says nothing about the order in which local variables are allocated. It doesn't even use the word "stack". It only requires that local variables have a lifetime that begins on entry to the nearest enclosing block (basically when execution reaches the {) and ends on exit from that block (reaching the }), and that each object has a unique address. It does acknowledge that two unrelated variables might happen to be adjacent in memory (for obscure technical reasons involving pointer arithmetic), but doesn't say when this might happen.
The order in which variables are allocated is entirely up to the whim of the compiler.
If you need to variables to be allocated in a particular order, you can wrap them in an array or a structure.然而又有了新的疑问,为什么
strcut
里的就一定要按顺序呢?为了对齐还要加 padding ,重排不是会更节省空间吗?
于是赶紧上 爆栈网 搜一搜,发现了解答