繁体   English   中英

在堆上分配数组时出现分段错误

[英]Segmentation fault when allocating array on the heap

假设我在堆上声明了一个大小超过堆限制的全局数组。 当然会抛出分段错误。 我的问题是,当我们这样做时会发生什么? 额外的整数会覆盖我们计算机系统中的某些部分吗?

这取决于您使用的操作系统(如果有)。

提供进程虚拟机抽象的系统 - 即任何 *nix 变体、Windows、一些 RTOS,例如 QNX

在这些系统中,虚拟 memory(地址空间)和提交的物理页面之间存在区别。 当写入关联的虚拟地址空间时,该进程获得物理页面。 因此,可以分配比系统上物理 memory 更大的堆块,并且堆可以按需增长。 系统可以使用分页来维护由实际 memory 支持的工作页面集,并将无法容纳的页面写入磁盘。 这就是许多人(错误地)描述为“虚拟内存”的东西。 值得注意的是,iOS、Android 和许多嵌入式系统没有寻呼机。

如果操作系统滥用 memory ,操作系统可能会杀死您的进程 - 例如,分配一个巨大的堆块,然后随机写入所有堆块。 操作系统可能会对进程可以拥有的虚拟地址空间或物理页数施加限制,并在超过此限制时终止进程。

超出堆块的末尾是 C 中的未定义行为 这可能会产生异常 - 或任何其他意外后果。 此时您是否也超出了整个堆,这是一个有争议的问题。

所有这些操作系统都将防止系统 memory 被进程破坏。

裸机系统,一些嵌入式操作系统

这些系统缺乏进程虚拟机抽象和与之配套的 memory 保护; 它们缺少分页,并且通常不允许分配比物理页面中所能容纳的更大的堆块。 覆盖已分配块的末尾将具有未定义的行为。

假设我在堆上声明了一个大小超过堆限制的全局数组。

您不能在堆上声明全局数组,因为您在编译时无权访问此 memory。

Probably you mean the array with the static storage duration and if the size of it will be larger than the memory reserved for the static storage duration objects the linker will throw the error.

memory 只能使用malloc系列函数动态分配运行时。

int a[500]; // 'a' is a static storage duration object

int foo()
{
   int b[500]; //'b' is an automatic storage duration object (most implementations use stack for it)
   static int c[500]; // 'c' is a static storage duration object
   int *d; //'d' is an automatic storage duration pointer (most implementations use 

   d = malloc(1000); // 'd' references the 1000 byte memory area allocated on the heap
}

如果您尝试分配的 memory 比可用的多,则分配 function 将返回NULL但不会失败。 如果您尝试访问不属于 object 的 memory - 这是未定义的行为,可能会导致分段错误。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM