当我在Windows和Linux上运行下面编写的代码时,我会得到两个不同的输出。
我正在使用gcc。当我在Windows上运行它时,我将“Seek”作为输出,而在Linux上运行它,我将“Hide”作为输出。 Windows和Linux的内存布局有什么不同,还是有其他原因导致输出不同?
int main()
{
int a=0;
int *b=(int *)malloc(sizeof(int));
if(&a>b)
printf("Hide");
else
printf("Seek");
return 0;
}
答案 0 :(得分:8)
是的,Windows和Linux以不同的方式布局。一些例子是here。例如,windows通常在内核和用户空间之间均匀地(以32位为单位)分割内存,而linux是3/1用户/内核。
编译器还可以在规范的限制范围内布置内存。这意味着llvm编译器,gcc以及它们的不同版本可以具有不同的输出。
优化还可以更改布局,甚至可以删除一些不是严格需要的变量。
此外,即使存储器从低到高分配,在释放一些其他存储器之后,新分配可能来自先前使用的区域并且再次变低。
简短回答:期望不相关变量之间的内存布局/位置不是一个好主意。
答案 1 :(得分:0)
malloc
的返回值未指定(可以是任何内容)。换句话说,在标准的任何部分都不保证返回值的可预测性。这是C语言标准的一部分,而不是特定于平台,并且与内存布局无关。从C99标准:
7.20.3内存管理功能
1连续调用calloc,malloc和。分配的存储的顺序和连续性 realloc函数未指定。如果指针返回指针 分配成功是适当对齐的,以便可以分配给 指向任何类型对象的指针,然后用于访问此类对象 或者分配的空间中的这些对象的数组(直到空格为止) 明确解除分配)。分配对象的生命周期延长 从分配到解除分配。每个这样的分配应 产生指向与任何其他对象不相交的对象的指针。该 指针返回指向的开始(最低字节地址) 分配空间。如果无法分配空间,则为空指针 回。如果请求的空间大小为零,则行为为 实现定义:返回空指针,或者 行为就像大小是一些非零值,除了 返回的指针不得用于访问对象
您遇到的是实现定义的行为,不保证将来会保留。实际上,它甚至不能保证在当前版本的Windows / Linux中保留。