代码之家  ›  专栏  ›  技术社区  ›  M-J

是什么导致此程序出现分段错误?

  •  0
  • M-J  · 技术社区  · 7 年前

    请通过在我的程序中调用以下函数来帮助我解决此SIGSEGV错误:

    int* calculateFitness(int** population, int** townDistancesMatrix, int chromoSize){
        int sum = 0;
        static int* Fitnesses;
        Fitnesses = malloc(sizeof(int)*chromoSize); 
        for(int i=0; i<chromoSize; i++){
            int indexOne = 0;
            int indexTwo = 0;
            for(int j=0; j<chromoSize-1; j++){
                indexOne = population[i][j];
                indexTwo = population[i][j+1];
                //printf("\n%d %d",indexOne-1,indexTwo-1);
                sum += townDistancesMatrix[indexOne-1][indexTwo-1];
            }
            indexOne = population[i][0];
            sum += townDistancesMatrix[indexTwo-1][indexOne-1];
            Fitnesses[i] = sum;
            sum = 0;
        }
        return Fitnesses;
    }
    

    对于较小的输入(如5个城镇),程序运行没有问题,所以我首先怀疑这是堆栈溢出,因为程序总是运行一段时间(直到所有运行的I值相似)( i=20 ))然后停止运行并给出此错误(在GDB中):

    程序接收信号SIGSEGV,分段故障。 计算能力为0x0000000008000b9b(人口=0x7ffffffedcd0,城镇距离矩阵=0x8403470,染色体大小=48),未计算1.c:97 97总和+=城镇距离矩阵[indexOne-1][indexTwo-1];

    calculateFitness 所以我认为这可能是由于我的函数中有大量的局部变量造成的,但是局部变量很少,而且很小,我的数组也是动态创建的,不在堆栈上运行(可能是嵌套循环的问题?)。

    我还运行了valgrind(虽然我还不太熟悉它的报告,我只是用它来获取一些提示),下面是报告:

    ==198== error calling PR_SET_PTRACER, vgdb might block
    ==198== Use of uninitialised value of size 8
    ==198==    at 0x108B41: calculateFitness (Untitled1.c:92)
    ==198==    by 0x108866: main (Untitled1.c:29)
    ==198==
    ==198== Use of uninitialised value of size 8
    ==198==    at 0x108B6E: calculateFitness (Untitled1.c:93)
    ==198==    by 0x108866: main (Untitled1.c:29)
    ==198==
    ==198== Invalid read of size 4
    ==198==    at 0x108B9B: calculateFitness (Untitled1.c:97)
    ==198==    by 0x108866: main (Untitled1.c:29)
    ==198==  Address 0x522d43c is 4 bytes before a block of size 192 alloc'd
    ==198==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck- 
    amd64-linux.so)
    ==198==    by 0x108A56: readDistances (Untitled1.c:74)
    ==198==    by 0x1087EB: main (Untitled1.c:19)
    ==198==
    ==198== Invalid read of size 8
    ==198==    at 0x108B87: calculateFitness (Untitled1.c:97)
    ==198==    by 0x108866: main (Untitled1.c:29)
    ==198==  Address 0x522d278 is 8 bytes before a block of size 384 alloc'd
    ==198==    at 0x4C2FB0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck- 
    amd64-linux.so)
    ==198==    by 0x108A20: readDistances (Untitled1.c:71)
    ==198==    by 0x1087EB: main (Untitled1.c:19)
    ==198==
    ==198==
    ==198== Process terminating with default action of signal 11 (SIGSEGV)
    ==198==  Access not within mapped region at address 0xFFFFFFFFFC000018
    ==198==    at 0x108B9B: calculateFitness (Untitled1.c:97)
    ==198==    by 0x108866: main (Untitled1.c:29)
    ==198==  If you believe this happened as a result of a stack
    ==198==  overflow in your program's main thread (unlikely but
    ==198==  possible), you can try to increase the size of the
    ==198==  main thread stack using the --main-stacksize= flag.
    ==198==  The main thread stack size used in this run was 8388608.
    
    //...
    
    ==198== LEAK SUMMARY:
    ==198==    definitely lost: 0 bytes in 0 blocks
    ==198==    indirectly lost: 0 bytes in 0 blocks
    ==198==      possibly lost: 0 bytes in 0 blocks
    ==198==    still reachable: 13,632 bytes in 70 blocks
    ==198==         suppressed: 0 bytes in 0 blocks
    

    我搜索了这个错误的部分,比如“仍然可以到达”,这似乎不是我需要注意的事情,但即使在搜索了第一部分之后,我也不确定它们的含义。我做错了什么?如果它真的是stackoverflow,除了递归之外,还有什么其他原因导致stackoverflow?

    1 回复  |  直到 7 年前
        1
  •  2
  •   bruno    7 年前
    int main(){
      int* population[POPSIZE];
    

    for(int i=0; i<chromoSize; i++){
        int indexOne = 0;
        int indexTwo = 0;
        for(int j=0; j<chromoSize-1; j++){
            indexOne = population[i][j];
            indexTwo = population[i][j+1];
    

    您可以从 人口 (发出信号) 瓦尔格林 ),您给的值为48 chromo_size (初始化 色浆 爆米花 等于20

    之后 indexOne 索引2 具有随机值,因此 城市距离矩阵 产生valgrind发出的seg故障信号

    主要的 scanf("%d",&chromo_size); 检查值是否为<= 爆米花 为了避免这个问题,增加 爆米花 能够使用输入文件运行


    另请注意 free(population) 是一个局部变量,它不在堆中分配