内存耗尽会导致分段故障吗?

Can segmentation fault be caused by exhaustion of memory ?

本文关键字:分段 故障 内存      更新时间:2023-10-16

我正在解决编解码的问题。

我已经编码了问题的算法,它在测试用例上运行良好。虽然,当我在codechef(在线)上运行它时,它会抛出分段错误。

我已经仔细检查了,我没有访问任何不可访问的内存位置,尽管我怀疑我的程序可能占用了大量的内存。

所以,我的问题是,当没有更多的内存可供程序执行时,可以抛出分段错误。比如c#中的OutOfMemoryException

这取决于您分配内存的方式以及在分配内存时是否检查错误。例如,malloc将在内存不足的情况下返回NULL。检查失败可能导致取消引用NULL,这将导致分割错误。如果你使用c++的new,它会抛出一个异常。

在现实中,当一个程序分配过多的内存时,它通常会使系统内存过度使用,并且在它的malloc开始返回NULL s之前,它的进程被一个OOM杀手杀死-除非大多数分配的内存实际上是未使用的。

正如Kerrek在评论中提到的,过度使用自动存储或调用堆栈过深可能导致seg故障,例如(在coliru上):

void foo(){ foo(); }
int main() {
    foo();
    return 0;
}

or (on coliru):

#include <iostream>
int main()
{
    int a[50000000];        
    std::cout << a[500];    
}

所以总而言之,你必须意识到你的系统的局限性,例如一些递归的暴力解决方案有时理论上应该工作,但相当不切实际(是的,这是一个模糊的例子,但OP没有提到正在解决的问题,也没有提到如何解决,所以我想给上面至少一些背景…)。

实际上有两种情况

1。如果您试图从调用堆栈中分配太多,那么您将收到一个信号。异常不能被捕获


int main() {
    try {
        std::array<int,10000000> arr;
        cout << arr[40] << endl;
    }
    catch(const std::exception& e) {
        cout << e.what() << endl;
    }
    return 0;
}

2。你试图分配太多的动态内存,那么你将收到一个异常


int main() {
    try {
        std::vector<int> arr;
        arr.resize(1000000000);
        cout << arr[40] << endl;
    }
    catch(const std::exception& e) {
        cout << e.what() << endl;
    }
    return 0;
}

你可以在ideone上试试