分段故障问题#n

时间:2015-06-17 22:38:16

标签: c++ segmentation-fault coredump

此命令行是否有误? FILE *TM = fopen("TM","r");

当我使用:g++ -O3 -march=corei7 -mtune=corei7 -std=c++11 prueba3.cpp -o prueba3 -lstdc++g++ -O3 -march=corei7 -mtune=corei7 -std=c++0x prueba3.cpp -o prueba3 -lstdc++编译我的代码然后运行可执行文件时,我得到了:

  

分段错误(核心转储)

当我用dbg调试代码时,得到了以下结果:

Reading symbols from ./a.out...done.
(gdb) b main
Breakpoint 1 at 0x400e59: file prueba3.cpp, line 10.
(gdb) r
Starting program: /home/alejo/Desktop/CM/a.out 

Breakpoint 1, main () at prueba3.cpp:10
10  {
(gdb) s
19      FILE *TM = fopen("TM","r");
(gdb) c
Continuing.
2053    2618
2618    3223
3223    3431

Program received signal SIGSEGV, Segmentation fault.
0x000000000040138e in main () at prueba3.cpp:98
98          A[b][a]=A[b][a]+1;
(gdb) q
A debugging session is active.

    Inferior 1 [process 3977] will be killed.

Quit anyway? (y or n) y

但是,我仍然不明白如何将它应用于我的代码,即:

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <iostream>
#include <string>

using namespace std;

int main()
{
int a,b,i,j,div,tm,ler;  
char string0[256],string1[256],string2[256];
/////////// 
//                          Load files:
//                          TM = size of the sqaure matrix
//                          REL = List of numbers
//                          LER = How many numbers are in REL
/////////// 
FILE *TM = fopen("TM","r");
if(TM == NULL)
{  
    printf("Can't open %s\n","TM");
    exit(1);
}
fscanf(TM,"%255s",string2);
tm = std::stoi(string2);
fclose(TM);

FILE *REL = fopen("REL","r");
if(REL == NULL)
{  
    printf("Can't open %s\n","REL");
    exit(1);
}

FILE *LER = fopen("LER","r");
if(LER == NULL)
{  
    printf("Can't open %s\n","LER");
    exit(1);
}
fscanf(LER,"%255s",string1);
ler = std::stoi(string1);
fclose(LER);

div=ler/2;
///////////     
//                          Allocate matrices
///////////     
int **A;
A = (int **)malloc(tm*sizeof(int*));
for(i=0;i<tm;i++)
{
    A[i]=(int*)malloc(tm*sizeof(int));
}

int *B;
B = (int*) malloc(ler*sizeof(int));
///////////     
//                          Set zero all elementes of allocated matrices
///////////     
if( A != NULL )
{
    for(i=0;i<tm;i++)
    {
        for(j=0;j<tm;j++)
        {
            A[i][j]=0;
        }
    }
}

if( B != NULL )
{
    for(i=0;i<ler;i++)
    {
        B[i]=0;
    }
}
/////////// 
//                          Put the LER numbers of REL in B[i] 
//                          with converting number-string to number-int
///////////     
for(i=0;i<ler;i++)
{
    fscanf(REL,"%255s",string0);
    B[i]=std::stoi(string0);
}
fclose(REL);
/////////// 
//                          Reocate numbers of C[i] in A[i][j]
/////////// 
for(i=0;i<div;i+=2)
{
    a=B[i]-1;
    b=B[i+1]-1;
    std::cout<<a<<"\t"<<b<<"\n";
    A[b][a]=A[b][a]+1;
    A[a][b]=A[a][b]+1;
}   
free(B);
/////////// 
//                          Print A[][]
/////////// 
for(i=0;i<tm;i++)
{
    for(j=0;j<tm;j++)
    {
        cout<<A[i][j]; 
    }
    cout<<"\n"; 
}
free(A);
}

我做错了什么?

以防万一,文件是:

REL:

2054
2619
2619
3224
3224
3432
194
2619
2619
3224
3224
3432
448

LER

30846

TM

3434

2 个答案:

答案 0 :(得分:2)

正如您自己指出的那样,Atm)的大小为3371 x 3371.文件REL.txt包含3383等数字(文件中的第138行)它大于A的尺寸。如调试器所示,这使您可以触及此部分的界限:

for(i=0;i<div;i+=2)
{
    a=B[i]-1;
    b=B[i+1]-1;
    std::cout<<a<<"\t"<<b<<"\n";
    A[b][a]=A[b][a]+1;           // b or a may be larger than 3371
    A[a][b]=A[a][b]+1;
}

您无需手动验证,但您可以实施它:

for(i=0;i<div;i+=2)
{
    a=B[i]-1;
    b=B[i+1]-1;
    std::cout<<a<<"\t"<<b<<"\n";

    if (a >= tm || b >= tm)
    {
        std::cerr << "Out of bounds!" << std::endl;
        continue;
    }

    A[b][a]=A[b][a]+1;           // b or a may be larger than 3371
    A[a][b]=A[a][b]+1;
}

答案 1 :(得分:-1)

int *B;
B = (int*) malloc(ler*sizeof(int));

...

if( B != NULL )
{
    for(i=0;i<tm;i++)
    {
        B[i]=0;
    }
}

如果tm > ler,这是一场灾难。

另外,为什么要在B中使这个代码有效,但是无条件地将值重新分配给B的每个元素?这些事情都没有意义。如果您要为每个元素重新赋值,为什么要将它们归零?如果您要在不检查其有效性的情况下访问阵列,为什么要在此检查其有效性?