这是代码未定义的行为吗?那么操作系统和堆呢?操作系统如何处理堆栈


char * s;
s[400] = 'd';

如果它不是未定义的行为,那么它是否意味着我不能任意访问堆栈外的RAM的任何部分?因此,每次操作系统启动一个进程时,它都会分配一个RAM区域,在那里我可以做一些讨厌的事情(除了malloc),因为操作系统会在进程结束后清理堆栈。

为什么操作系统不能在进程结束后清理堆?这是否意味着堆与所有其他进程共享?

如果我在堆栈中放入了太多的数据,这是缓冲区溢出,但是我可以在堆栈中放入多少数据?

是否与操作系统、ram大小或cpu缓存有关?

是,它的行为是未定义的。

s没有初始化,所以s[400]最多是内存中某个不确定的位置。

编辑:

你的问题的最后三段与我们一直在讨论的两行代码几乎没有关系。s[400] = 'd';的不确定性与堆栈、堆、进程或其他任何东西几乎没有关系。s未初始化,包含垃圾;它可以指向内存中的任何地方,也可以不指向任何地方。s[400]最多是一个char对象,位于s所存储的垃圾地址指定的未定义位置之外400字节。

如果你明白了,你可能还有问题。我建议发布一个没有代码示例的新问题。

部分回答你的一些问题:

你的程序可能不合法地尝试访问任何不属于它创建的对象的内存(通过对象定义,如char foo[1000];或通过分配,如char *ptr = malloc(1000);)。在特定的实现中,可能是在任何声明的对象之外的某个内存区域,您可以对其进行处理,但是没有安全或可移植的方法来这样做——也没有很好的理由。如果您需要访问内存,请先分配。

C语言本身甚至没有提到"堆栈"或"堆";这些是实现细节。

不,堆通常不会在进程之间共享。通常,当程序完成时,操作系统会整齐地回收所有堆栈分配和堆分配的内存。(C标准没有这么说,因为它几乎不关心程序执行之外发生的事情,但这几乎是普遍正确的,除了在某些嵌入式系统中。)

是的,这是未定义的行为,因为它没有指向您的应用程序分配的内存块。

最新更新