背景

我习惯于使用VScode刷一些算法题,但是很多时候在本地需要开大内存的时候(具体来说是在主函数里面),运行的时候IDE会提示Segmentation fault

比如以下代码:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    int blocks[1001][1001]{0};
	...
}

这时候这个数组实际上仅仅占用了1001 * 1001 * 8B ≈7.64MB的内存,但是却出现了Segmentation fault错误。但是在OJ上面是没有问题的,能够AC。

其实解决方法也很简单,不要定义在主函数里面,而是直接开全局变量就行了。但是本着打破砂锅问到底的精神,我对这个现象进行了一些探索。

解释

在C++的程序中,全局变量是存储在上的,而局部变量是存储在上的。如果在主函数里面定义, 当在主函数中定义一个大数组时,由于栈空间有限,很可能会导致栈溢出,从而出现Segmentation fault错误。

那为什么OJ上面又可以跑呢?

其实是可以通过设置连接器的传入参数,来自定义栈分配的内存大小上限的。

以我的VSCode中配置为例,在你的项目文件夹下的.vscode文件夹中,应该有一个tasks.json文件,在里面修改配置,在tasks.args添加以下命令:

-Wl,--stack,512000000

这个命令的含义:

  • -Wl: 表示后面是传给连接器的命令
  • --stack,512000000,设置栈的内存分配上限为512000000B

改完应该像这样:

{
    "tasks": [
        {
            "type": "cppbuild",
            "label": "C/C++: g++.exe 生成活动文件",
            "command": "C:\\MinGW\\bin\\g++.exe",
            "args": [
                "-fdiagnostics-color=always",
                "-g",
                "${file}",
                "-o",
                "${fileDirname}\\${fileBasenameNoExtension}.exe",
                "-Wl,--stack,512000000"
            ],
            "options": {
                "cwd": "${fileDirname}"
            },
            "problemMatcher": [
                "$gcc"
            ],
            "group": {
                "kind": "build",
                "isDefault": true
            },
            "detail": "调试器生成的任务。"
        }
    ],
    "version": "2.0.0"
}

这样以后,就算主函数里面开大内存也不会报错了。


标题:解决OI中使用g++编译器时出现的Segmentation fault错误
作者:shiquda
地址:https://shiquda.link/solve-segmentation-fault
除非特别说明,本博客上的所有内容均在CC BY-SA 4.0许可下提供。 如需转载请注明作者与来源,谢谢!