【问题标题】:Segmentation fault (core dumped) with large arrays [closed]大型阵列的分段错误(核心转储)[关闭]
【发布时间】:2014-07-09 16:58:24
【问题描述】:

我是 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 时,不会引发错误并且程序按预期执行。我知道问题出在分配给我的物理内存上,但是有办法解决吗?有人可以指导我需要进行哪些修改吗?

【问题讨论】:

  • 当然。您需要在调试器中运行您的程序。在 Linux 上,这可能意味着 gdb。
  • V1 和 V2 太大,堆栈溢出。您需要使它们成为全局的、静态的,或者更好的是动态分配它们。
  • I know the problem is with physical memory allocated to me 这不是问题。使用std::vector&lt;double&gt; 而不是那些数组。
  • 谢谢 std::vector 运行良好,代码现在运行良好。谢谢大家。
  • 写代码时你的空格键有问题吗?

标签: c++ linux core


【解决方案1】:

这是堆栈。您正在使用大约 16Mb 的堆栈来存储这两个双精度数组(每个双精度数组 8 个字节 * 2 个数组 * 1,000,000)。

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

ulimit -s 32000

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

如果您像这样将它们移出堆栈(并使用一些空白行使代码更易于阅读:)),那么它就可以正常工作。但是,如上所述,我还建议您查看 vector 而不是使用 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);
}

【讨论】:

  • 谢谢,这肯定会帮助我组织好我的代码。
  • 另外,为您定义了 PI。在顶部添加这个,你可以使用 M_PI:#define _USE_MATH_DEFINES #include
  • 默认堆栈大小是多少?
  • 在这里(OS X)看起来像 8Mb,显然在 Ubuntu 上也是如此。试试 ulimit -s 看看?
【解决方案2】:

保罗 R 是对的。在函数中声明的变量使用“堆栈”。您可以为局部变量使用多少空间是有限制的。

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

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

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

一种快速而简单的解决方案是使用limit/ulimit。缺点是您必须在运行程序之前使用此命令。简单地使数组全局更容易......

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

【讨论】:

    【解决方案3】:

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

    您可以使用std::vector 标准模板类(即使您在堆栈上分配了一个向量,它的数据也在堆中)。所以将#include &lt;vector&gt; 添加到包含的标题中,然后编写类似

    的代码
      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 tutorial;顺便说一句,使用和学习 C++11(不是一些早期的 C++ 标准)。所以使用最近的编译器(例如GCC 4.9,使用g++ -std=c++11 -Wall -g....进行编译)并使用gdb 调试器。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-28
      • 1970-01-01
      • 1970-01-01
      • 2012-11-20
      • 1970-01-01
      相关资源
      最近更新 更多