c - 这段代码是未定义的行为吗?操作系统和堆怎么样?操作系统如何处理堆栈?

标签 c operating-system heap-memory stack-memory

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

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

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

如果我在堆栈中放入太多数据,那就是缓冲区溢出,但是我可以在堆栈中放入多少呢?是操作系统限制、RAM 大小限制还是 CPU 缓存限制?

最佳答案

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

s 未初始化,因此 s[400] 充其量只是内存中某个不确定的位置。

编辑:

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

如果您理解了这一点,您可能还有疑问。我建议发布一个没有代码示例的新问题。

部分回答您提出的一些问题:

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

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

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

关于c - 这段代码是未定义的行为吗?操作系统和堆怎么样?操作系统如何处理堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7211609/

相关文章:

c - 我的动态数组有问题

linux - 使用网络开发语言与系统命令交互

C# 输出参数

计算进程的内存使用

c - 移动棋盘上的骑士的程序

c - 为什么 OMP 任务运行速度比 OMP 慢?

python - 如何判断是否安装了rosetta?

c - 如何获取进程信息?

c++ - 如何实现内存堆

c++ - 在函数外访问堆栈对象