具有大型阵列的分段故障(核心转储)

Segmentation fault (core dumped) with large arrays

本文关键字:核心 转储 故障 分段 大型 阵列      更新时间:2023-10-16

我是C++编程的新手,曾编写过以下C++代码:

//colpitts high freq 1 GHz working with delay
#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const double pi = 3.1415926;
int main(){
    double c0, dx, dt,C1,C2,L,fs,Ceq, freq, tau, Rload, gload, Re, ge,gm,gc1,gc2,ic1,ic2,il,gl ;
    c0=20000000000;
    dx=0.01;
    dt=dx/(2 * c0);
    cout<<dt<<"n";
    double V1 [1000000]={};
    double V2 [1000000]={};
    V1[0]=1e-3; 
    C1=1e-12;
    C2=5e-12;
    L=30.4e-9;
    fs=4e12;
    Ceq=(C1 * C2)/(C1+C2);
    cout<<Ceq<<"n";
    freq=1/(2 * pi * (sqrt(L*Ceq)));
    cout<<freq<<"n";
    tau=1/freq;
    cout<<tau<<"n";
    Rload=50;
    Re=1e6; 
    ge=1/Re;
    cout<<ge<<"n";
    gm=0;
    gc1=(C1)/dt;
    cout<<gc1<<"n";
    ic1=-((C1)/dt) * V1[0];  
    cout<<ic1<<"n";
    gc2=(C2)/dt;
    cout<<gc2<<"n";
    ic2=-((C2)/dt) * V2[0];
    cout<<ic2<<"n";
    gl=dt/(L);
    cout<<gl<<"n";
    il=gl * (V2[0]-V1[0]);
    cout<<il<<"n";
    gload=1/Rload;
    cout<<gload<<"n";
    return (0);
}

当我在Linux机器上运行它时,它会抛出一个分段错误(核心转储(,但当我将数组更改为100000时,不会抛出任何错误,程序会按预期执行。我知道问题出在分配给我的物理内存上,但有办法解决吗?有人能告诉我需要做哪些修改吗?

它是堆栈。您正在使用大约16Mb的堆栈来存储这两个双字节数组(每双字节8字节*2个数组*1000000(。

像这样设置一个更大的堆栈:

ulimit -s 32000

确实解决了问题。但是在堆栈中放入16Mb的数据块并不是一个好主意。

如果像这样将它们从堆栈中移出(并使用一些空行使代码更易于阅读:(,那么它就可以正常工作。然而,如上所述,我也建议您查看向量,而不是使用C风格的原始数组:

http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-to-stdvector-Part-1.htm

#include <iostream>
#include <cmath>
#include <string>
#include <cstring>
using namespace std;
const double pi = 3.1415926;

double V1 [1000000]={};
double V2 [1000000]={};

int main(){
    double c0, dx, dt,C1,C2,L,fs,Ceq;
    double freq, tau, Rload, gload; 
    double Re, ge,gm,gc1,gc2,ic1,ic2,il,gl ;
    c0=20000000000;
    dx=0.01;
    dt=dx/(2 * c0);
    cout<<dt<<"n";
    V1[0]=1e-3; 
    C1=1e-12;
    C2=5e-12;
    L=30.4e-9;
    fs=4e12;
    Ceq=(C1 * C2)/(C1+C2);
    cout<<Ceq<<"n";
    freq=1/(2 * pi * (sqrt(L*Ceq)));
    cout<<freq<<"n";
    tau=1/freq;
    cout<<tau<<"n";
    Rload=50;
    Re=1e6; 
    ge=1/Re;
    cout<<ge<<"n";
    gm=0;
    gc1=(C1)/dt;
    cout<<gc1<<"n";
    ic1=-((C1)/dt) * V1[0];  
    cout<<ic1<<"n";
    gc2=(C2)/dt;
    cout<<gc2<<"n";
    ic2=-((C2)/dt) * V2[0];
    cout<<ic2<<"n";
    gl=dt/(L);
    cout<<gl<<"n";
    il=gl * (V2[0]-V1[0]);
    cout<<il<<"n";
    gload=1/Rload;
    cout<<gload<<"n";
    return (0);
}
Paul R是对的。函数中声明的变量使用"堆栈"。可以用于局部变量的空间是有限的。

他建议将这些局部数组声明为全局、静态、动态分配,这意味着这些变量将不使用堆栈空间。使用STL中的矢量也可以。

此链接可能会让您了解堆栈空间大小。

https://stackoverflow.com/a/1825996/3813353

一个快速而肮脏的解决方案是使用limit/ulimit。缺点是在运行程序之前必须使用此命令。简单地使阵列全局化变得更加容易。。。

通常,当你遇到堆栈大小的问题时,你会有失控或无限递归。对递归函数的每次调用可能不会使用堆栈中的太多数据,但如果函数继续调用自己,最终会耗尽堆栈空间。

实际上,堆栈上的数据太多了。

您可以使用std::vector标准模板类(即使您在堆栈上分配了一个向量,它的数据也在堆中(。因此,将#include <vector>添加到包含的标头中,然后编写之类的代码

  std::vector<double> v1, v2;
  v1.push_back(2.512);
  v1.push_back(3.17);
  v2.resize(37);
  v2[0] = v1[0] + v1[1]; 
  v2[17] = sqrt(10.0) + 11.0;

阅读一些STL教程;BTW,使用和学习C++11(不是一些早期的C++标准(。因此,请使用最新的编译器(例如GCC 4.9,使用g++ -std=c++11 -Wall -g进行编译…(并使用gdb调试器。