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

问题描述 投票:-1回答:2

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

c
2个回答
1
投票

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

提供process virtual machine抽象的系统-也就是说,任何* nix变体,Windows,某些RTOS,例如QNX

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

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

在C中,

超出堆块的末尾是未定义的行为。这可能会产生异常-或任何其他意外结果。目前还不能覆盖整个堆是一个有争议的问题。

所有这些操作系统都将防止进程浪费系统内存。

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

这些系统缺少随之而来的进程虚拟机抽象和内存保护;它们缺少分页,并且通常将不允许分配比物理页面中可以容纳的更大的堆块。覆盖已分配块的末尾将具有不确定的行为。


0
投票

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

您无法在堆上声明全局数组,因为您在编译时无法访问此内存。

可能是指具有静态存储持续时间的数组,如果它的大小大于为静态存储持续时间对象保留的内存,则链接器将引发错误。

heap内存只能使用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
}

如果您尝试分配的内存超过可用内存,则分配函数将返回NULL,但不会失败。如果尝试访问不属于该对象的内存-这是未定义行为,则可能会导致分段错误。

© www.soinside.com 2019 - 2024. All rights reserved.