分割故障139(核心转储)C ++更改操作系统后

我有一个工作程序来分析C ++中的数据,目前已经产生了35个成功的数据文件。 我在Code:Blocks工作时使用Scientific Linux,除了一些涉及非常大的网格尺寸(1000×1000 +)的小错误,它完美地工作,并且正是我所期望的。

我最近切换到Ubuntu,并期望它能正常工作,而不是。 它接受初始input(第一个粒子切换),但立即崩溃与分段错误139.我试图在Windows中运行它,而不是我的双启动,但它似乎并不认可本地文件系统,所以我被迫寻求帮助。

这是一个很长的程序,所以我会重现整个事情。 我提前道歉。

// This program converts the column output of a 1D PIC code into a workable solution #include <iostream> #include <fstream> #include <math.h> using namespace std; double calculateXMaximum(double arraymax[], int size) { double maximum = 0; for (int k = 1; k < size/2; k++) { if(arraymax[2*k] > maximum) { maximum = arraymax[2*k]; } } return maximum; } double calculateXMinimum(double arraymin[], int size) { double minimum = 0; for (int k = 1; k < size/2; k++) { if(arraymin[2*k] < minimum) { minimum = arraymin[2*k]; } } return minimum; } double calculatePXMaximum(double arraymax[], int size) { double maximum = 0; for (int k = 1; k < size/2; k++) { if(arraymax[2*k+1] > maximum) { maximum = arraymax[2*k+1]; } } return maximum; } double calculatePXMinimum(double arraymin[], int size) { double minimum = 0; for (int k = 1; k < size/2; k++) { if(arraymin[2*k+1] < minimum) { minimum = arraymin[2*k+1]; } } return minimum; } int main() { // Variables settable before running program - will set up initialisation later. double xmin = 0; double xmax = 0; double pmin = 0; double pmax = 0; int xni = 0; double xntemp = 0; double deltax = 0; int xi; // X interpolates, defined from console for resolution of diagram int pnj = 0; double pntemp = 0; double deltap = 0; int pi; int type; double modifier; // Determines momentum modifier! cout << "For particle type, enter 1 (e-) or 2 (p+)" << endl; cout << "Particle type: "; cin >> type; if (type == 2) { modifier = 1836; } else { modifier = 1; } ifstream inputFile; ofstream outputFile; inputFile.open ("/home/Nick/fi020000.dat"); outputFile.open ("/home/Nick/fi20k.dat"); int dataformat[2]; for(int rd = 0; rd < 2; rd++) { dataformat[rd] = 0; inputFile >> dataformat[rd]; } int records = dataformat[1] + 2; double data[records]; cout << "Number of particles: " << dataformat[1]/2 << endl; // Introduction of data from input data file loop. Produces records. for (int count = 0; count < records; count++) { inputFile >> data[count]; } // Calling functions for xmin and xmax. May streamline later xmax = calculateXMaximum(data, records) * 1.1; cout << "Maximum x value: " << xmax << endl; xmin = calculateXMinimum(data, records) * 1.1; cout << "Minimum x value: " << xmin << endl; pmax = calculatePXMaximum(data, records) * 1.1 / modifier; cout << "Maximum p value: " << pmax << endl; pmin = calculatePXMinimum(data, records) * 1.1 / modifier; cout << "Minimum p value: " << pmin << endl; // Definition of bin size cout << "Entire desired number of x bins: "; cin >> xi; const int xip = xi; cout << "Enter desired number of p bins: "; cin >> pi; const int pip = pi; cout << "Grid is " << xip << " x " << pip << endl; // Calculate DELTA X and DELTA P deltax = (xmax - xmin)/(xip); deltap = (pmax - pmin)/(pip); cout << "Resolution of x: " << deltax << endl; cout << "Resolution of p: " << deltap << endl; int phaseSpace [xip][pip]; for(int i=0; i<xip; i++) { for(int j=0; j<pip; j++) { phaseSpace[i][j] = 0; } } for (int phasecount=1; phasecount < (records/2)-1; phasecount++) { xntemp = (data[2*phasecount] - xmin)/deltax; xni = floor(xntemp); pntemp = ((data[(2*phasecount)+1] / modifier) - pmin)/deltap; pnj = floor(pntemp); phaseSpace[xni][pnj] = phaseSpace[xni][pnj] + 1; } for (int xoutcount = 0; xoutcount < xip; xoutcount++) { for (int poutcount = 0; poutcount < pip; poutcount++) { outputFile << xmin+((xoutcount+0.5)*deltax) << " " << pmin+((poutcount+0.5)*deltap) << " "<< phaseSpace[xoutcount][poutcount] << endl; } outputFile << endl; } cout << "Program complete" << endl; return 0; } 

我的意图是在本周末完成一个30页的报告,现在我用来做这个的程序已经完全崩溃了。 我不是计算机科学家 – 我是一名物理学家,不到一个月前我就学会了C ++。 因此,我不知道发生了什么事情。 我知道这个话题已经被看到了很多,但我不能真正理解这个build议。

编辑:堆栈跟踪是:

 #0 0x4010af ?? () (??:??) #1 0x7ffff7215ea5 __libc_start_main() (/lib/x86_64-linux-gnu/libc.so.6:??) #2 0x4017f1 ?? () (??:??) 

EDIT2:Valgrind结果

 ==4089== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info ==4089== Command: ./Analysis ==4089== For particle type, enter 1 (e-) or 2 (p+) Particle type: 2 ==4089== Warning: client switching stacks? SP change: 0x7fefff9c0 --> 0x7fe6d7118 ==4089== to suppress, use: --max-stackframe=9603240 or greater ==4089== Invalid write of size 8 ==4089== at 0x4010AF: ??? (in /home/paladin/Contour/Analysis/bin/Release/Analysis) ==4089== by 0x5673EA4: (below main) (libc-start.c:260) ==4089== Address 0x7fe6d7118 is on thread 1's stack ==4089== ==4089== ==4089== Process terminating with default action of signal 11 (SIGSEGV) ==4089== Access not within mapped region at address 0x7FE6D7118 ==4089== at 0x4010AF: ??? (in /home/paladin/Contour/Analysis/bin/Release/Analysis) ==4089== If you believe this happened as a result of a stack ==4089== overflow in your program's main thread (unlikely but ==4089== possible), you can try to increase the size of the ==4089== main thread stack using the --main-stacksize= flag. ==4089== The main thread stack size used in this run was 8388608. ==4089== ==4089== Process terminating with default action of signal 11 (SIGSEGV) ==4089== Access not within mapped region at address 0x7FE6D7111 ==4089== at 0x4A256A0: _vgnU_freeres (in /usr/lib/valgrind/vgpreload_core-amd64-linux.so) ==4089== If you believe this happened as a result of a stack ==4089== overflow in your program's main thread (unlikely but ==4089== possible), you can try to increase the size of the ==4089== main thread stack using the --main-stacksize= flag. ==4089== The main thread stack size used in this run was 8388608. ==4089== ==4089== HEAP SUMMARY: ==4089== in use at exit: 17,520 bytes in 4 blocks ==4089== total heap usage: 4 allocs, 0 frees, 17,520 bytes allocated ==4089== ==4089== LEAK SUMMARY: ==4089== definitely lost: 0 bytes in 0 blocks ==4089== indirectly lost: 0 bytes in 0 blocks ==4089== possibly lost: 0 bytes in 0 blocks ==4089== still reachable: 17,520 bytes in 4 blocks ==4089== suppressed: 0 bytes in 0 blocks ==4089== Rerun with --leak-check=full to see details of leaked memory ==4089== ==4089== For counts of detected and suppressed errors, rerun with: -v ==4089== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 2 from 2) Segmentation fault (core dumped) 

错误发生在ifstream inputFile语句处。

编辑3:按要求,控制台会话:

 paladin@paladin:~/Programming/Contour Constructor 2/bin/Debug$ ./Contour\ Constructor\ 2 For particle type, enter 1 (e-) or 2 (p+) Particle type: 2 Segmentation fault (core dumped) 

input文件中有1200402行,对应PIC代码中的600200个粒子加上2条描述行。

编辑4: 在这里黑暗完整的镜头,但我原来编译在GCC 4.4.7在科学的Linux下。 我现在正在使用最新的Ubuntu版本(4.8.1)。 在过渡期间有什么变化会使我正在使用的文件的大小无效?

这里最重要的一点是valgrind认为你正在切换线程 – 当然,从你所显示的代码来看,你并没有使用多线程。 由于多线程程序中的每个线程都有自己的栈,因此valgrind会假设栈指针的变化超过了某个阈值(请参阅valgrind输出中提到的–max-stackframe),以便切换到另一个线程。

实际上,发生了什么是你创建了一个巨大的堆栈帧,确切地说是9603240个字节。 这超过了8MB左右,你可能会得到默认情况下。 您可以通过在shell中查看当前的软限制:

 $ ulimit -s 8192 

换句话说,堆栈被限制为8MB。 如果超过这个限制,Linux会认为发生了一些不好的事情,并终止你的进程。

您可以使用的一个即时修复方法是提高限制,或者将其设置为无限制:

 $ ulimit -s 16384 # 16MB stack $ ulimit -s unlimited # "unlimited" stack 

这应该阻止你的进程崩溃,并解释了为什么它在一个盒子上工作正常,而不是另一个(它的工作可能有一个较高的堆栈大小限制默认设置)。

现在,从设计角度来看,创建堆栈框架通常是一个糟糕的主意 。 对于大的分配,你应该使用堆内存,所以像这样:

 double data[records]; 

可以被替换

 double *data = new double[records]; // use data ... delete[] data; 

从堆中分配和释放内存。 这将使您能够避免这样的问题。 或者,你总是可以使用标准容器之一,如std :: vector <>`来避免这个问题。

如果仅在大输入大小时才会看到此问题,则创建phaseSpace时可能会发生堆栈溢出,因为这可能是一个相当大的数组。 如果使用std::vector而不是plain数组,则应该避免这样的问题:

 #include <vector> // ... // A vector containing vectors containing integers. // Initialized to contain the appropriate amount of space filled with zeros std::vector< std::vector<int> > phaseSpace(pip, std::vector<int>(xip, 0)); 

其余的代码可能和向量一样。


或者,如果xnipni超出范围,您将覆盖随机存储器。 您可以添加输出语句来显示这些值,看看是否看起来错了。

我很惊讶这个程序甚至编译:你正在声明在编译时无法确定的大小的数组,如下所示。 你能告诉你正在使用哪个编译器吗?

 int records = dataformat[1] + 2; double data[records]; 

这是它可能看起来像使用std :: vector而不是本地数组。

 // This program converts the column output of a 1D PIC code into a // workable solution #include <cmath> #include <fstream> #include <iostream> #include <limits> #include <vector> double calculateXMaximum(const std::vector<double>& arraymax) { double maximum = -std::numeric_limits<double>::max(); for (unsigned k = 1; k < arraymax.size()/2; ++k) { maximum = std::max(arraymax[2*k], maximum); } return maximum; } double calculateXMinimum(const std::vector<double>& arraymin) { double minimum = std::numeric_limits<double>::max(); for (unsigned k = 1; k < arraymin.size()/2; ++k) { minimum = std::min(arraymin[2*k], minimum); } return minimum; } double calculatePXMaximum(const std::vector<double>& arraymax) { double maximum = -std::numeric_limits<double>::max(); for (unsigned k = 1; k < arraymax.size()/2; ++k) { maximum = std::max(arraymax[2*k+1], maximum); } return maximum; } double calculatePXMinimum(const std::vector<double>& arraymin) { double minimum = std::numeric_limits<double>::max(); for (unsigned k = 1; k < arraymin.size()/2; ++k) { minimum = std::min(arraymin[2*k+1], minimum); } return minimum; } int main() { // Variables settable before running program // - will set up initialisation later. int xni = 0; double xntemp = 0; int xi; // X interpolates, defined from console for resolution of diagram int pnj = 0; double pntemp = 0; int pi; int type; // Determines momentum modifier! std::cout << "For particle type, enter 1 (e-) or 2 (p+)\n"; std::cout << "Particle type: "; std::cin >> type; const double modifier = (type == 2) ? 1836.0 : 1.0; std::ifstream inputFile("fi020000.dat"); std::ofstream outputFile("fi20k.dat"); int dataformat[2]; inputFile >> dataformat[0]; inputFile >> dataformat[1]; int records = dataformat[1] + 2; std::vector<double> data(records, 0.0); std::cout << "Number of particles: " << dataformat[1]/2 << std::endl; // Introduction of data from input data file loop. Produces records. for (int count = 0; count < records; ++count) { inputFile >> data[count]; } // Calling functions for xmin and xmax. May streamline later const double xmax = calculateXMaximum(data) * 1.1; std::cout << "Maximum x value: " << xmax << std::endl; const double xmin = calculateXMinimum(data) * 1.1; std::cout << "Minimum x value: " << xmin << std::endl; const double pmax = calculatePXMaximum(data) * 1.1 / modifier; std::cout << "Maximum p value: " << pmax << std::endl; const double pmin = calculatePXMinimum(data) * 1.1 / modifier; std::cout << "Minimum p value: " << pmin << std::endl; // Definition of bin size std::cout << "Entire desired number of x bins: "; std::cin >> xi; const int xip = xi; std::cout << "Enter desired number of p bins: "; std::cin >> pi; const int pip = pi; std::cout << "Grid is " << xip << " x " << pip << std::endl; // Calculate DELTA X and DELTA P const double deltax = (xmax - xmin)/(xip); const double deltap = (pmax - pmin)/(pip); std::cout << "Resolution of x: " << deltax << std::endl; std::cout << "Resolution of p: " << deltap << std::endl; std::vector< std::vector<int> > phaseSpace(xip, std::vector<int>(pip, 0)); for (int phasecount=1; phasecount < (records/2)-1; ++phasecount) { xntemp = (data[2*phasecount] - xmin)/deltax; xni = std::floor(xntemp); pntemp = ((data[(2*phasecount)+1] / modifier) - pmin)/deltap; pnj = std::floor(pntemp); phaseSpace[xni][pnj] = phaseSpace[xni][pnj] + 1; } for (int xoutcount = 0; xoutcount < xip; ++xoutcount) { for (int poutcount = 0; poutcount < pip; ++poutcount) { outputFile << xmin+((xoutcount+0.5)*deltax) << " " << pmin+((poutcount+0.5)*deltap) << " " << phaseSpace[xoutcount][poutcount] << "\n"; } outputFile << "\n"; } std::cout << "Program complete" << std::endl; return 0; } 

我删除了一些std::endl调用,并用"\n"替换它们以避免不必要的I / O缓冲区刷新。

我对你的分钟和最大值的计算方式做了一些小改动。

我移动了一些变量声明,并在可能的情况下使它们成为const

重要提示:您应该在阅读输入时检查ifstream的状态。 就目前而言, 您可以阅读文件的末尾,永远不会知道 。 对data数组的内容似乎也存在误解。 看起来好像你认为它包含了你的两条主要的描述性的线条。 但是,您已经从流中将这两个数字拉成了dataformat ,所以您不需要考虑它们。

一个非常小的手验证测试输入和输出数据将是有用的。