Windows和Linux操作系统的内存布局有什么不同吗?

Lal*_*wal 4 c linux memory windows layout

当我在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;
}
Run Code Online (Sandbox Code Playgroud)

Pau*_*bel 8

是的,Windows和Linux以不同的方式布局.这里有一些例子.例如,windows通常在内核和用户空间之间均匀地(以32位为单位)分割内存,而linux是3/1用户/内核.

编译器还可以在规范的限制范围内布置内存.这意味着llvm编译器,gcc以及它们的不同版本可以具有不同的输出.

优化还可以改变布局,甚至删除一些不是严格需要的变量.

此外,即使存储器从低到高分配,在释放一些其他存储器之后,新分配可能来自先前使用的区域并且再次变低.

简短回答:期望不相关变量之间的内存布局/位置不是一个好主意.


Mik*_*wan 0

返回值malloc未指定(可以是任何值)。换句话说,标准的任何部分都不保证返回值的可预测性。这是 C 语言标准的一部分,而不是特定于平台的,并且与内存布局没有真正的关系。来自C99标准:

\n\n
\n

7.20.3 内存管理函数

\n\n

1 通过连续调用 calloc、malloc 和\n realloc 函数分配的存储的顺序和连续性未指定\xef\xac\x81ed。如果分配成功,返回的指针将被适当对齐,以便可以将其分配给指向任何类型对象的指针,然后用于访问分配的空间中的此类对象或此类对象的数组(直到空间被显式释放)。已分配对象的生命周期从分配开始一直延伸到释放为止。每个这样的分配将产生一个指向与任何其他对象不相交的对象的指针。返回的指针指向分配空间的起始位置(最低字节地址)。如果无法分配空间,则返回空指针。如果请求的空间大小为零,则行为是\n 实现定义的:返回空指针,或者\n 行为就像大小是某个非零值,除了\n n 返回的指针不得用于访问对象

\n
\n\n

您遇到的是实现定义的行为,不能保证将来仍然有效。事实上,甚至不能保证它在当前版本的 Windows/Linux 中保持不变。

\n

  • 标准语与他的问题无关。 (2认同)
  • 您为什么认为这是用于生产的代码?也许他只是在探索一些东西,也许他想知道堆栈和堆分配到哪里。事实上,这是特定于实现的,这并没有说明这些知识的好奇心,而这似乎是他的问题的重点。 (2认同)