【问题标题】:Segfault during calculation loop计算循环期间的段错误
【发布时间】:2016-02-16 08:11:30
【问题描述】:

我写了一组代码来解决一些物理问题。不幸的是,我无法显示整个代码(它们太长并且属于私人项目),但大致而言,我的程序结构是

double **array1;  // declared globally
double **array2;  // because there are a lot of functions using array1 & 2

main{
    double x;
    fscanf(input);  // reading an input file
    fclose(input);  // input file have information about dimension of array
                    // and step to do different calculation

    array = *calloc(~);
    array[i] = calloc(~);   // making 2d array with dimension from input file

    for(i=0;i<large number;i++){
    // (doing physical calculation using array1 and array2);       
        if(i==some step from input file){
            // (calculation using array2)
            x = array1[k][0]-array1[l][0] ...   // !!SEGFAULT!!
    }
}

问题在于,无论数组的维度或输入文件中包含的任何其他变量如何,当程序接近 !!SEGFAULT!!区域,它会产生分段错误(使用 gdb ...)。 “某个步骤”可以是 1、10、100,...,我尝试了几个不同输入文件内容的测试,但程序仅在该区域产生段错误。 Valgrind 说没有内存泄漏。

奇怪的是,在程序开始时,gdb 说array1 的地址是(double **) 0x68e410,直到程序到达问题点才改变。此时array1的地址变为(double **)0x3ff223bf06cdec4d,我无法访问array1的任何元素。

如果我将“some step”设置得非常大,我可能会避免段错误问题,但这不是解决方案并且会污染我们项目的计算过程......这个问题的根源是什么?

【问题讨论】:

  • 地址更改表明某些内容会覆盖内存。在这种情况下,SegFault 将是早期内存损坏的症状,可能在“(使用 array2 计算)”中。通常,替换数组地址的数据字节模式可以暗示导致此问题的语句。
  • 很难说没有整个代码。通过注释掉函数来排除函数,直到您的段错误消失。取消注释部分,直到它回来。重复直到找到它发生的确切位置。之后用你的发现更新你的问题。
  • 从您发布的几行中得出的脑震荡充其量只是很好的猜测。您拥有所有代码、调试器、编译器、环境、数据等,而我们只能看到十几行不相关的代码。如果您无法发布更多信息,那么 SO 无法帮助您。您需要对此进行调试。

标签: c segmentation-fault


【解决方案1】:

鉴于信息不足...

这两行是问题的根源。

array = *calloc(~);
array[i] = calloc(~); 

举个具体的例子:

int **array = NULL;
// notice, in following line that the second parameter to calloc() 
// is the size of a pointer
array = calloc( 100, sizeof(int*) );

// each entry in the array[] 
// must be set to point to some (more) allocated memory
for( int i=0; i<100; i++ )
{
    array[i] = calloc( 20, sizeof( int ) );
}

当然,每次调用calloc() 之后都必须进行检查以确保返回的值不为 NULL。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-14
    相关资源
    最近更新 更多