如何纠正分段错误?

时间:2014-12-29 05:50:41

标签: c++ segmentation-fault core dump

下面的程序显示错误:"分段错误(核心转储)"。

它应该使用向量显示平面文件记录,读取每行的记录并获取字段并推回到向量r_record。并推回桌面。

//.. includes
#define LIMIT 72
#define FIELD 25

using namespace std;
typedef vector <string> record_t;
typedef vector <record_t> table_t;
char line[FIELD];   
string s_field;
table_t table;
record_t r_record;

void getField(char s[LIMIT])
{
    char field[LIMIT];      
    int i=0;
    r_record.clear();
    while(s[i]  != '\n')
    {   
        if (s[i] != '\t' )
        {                                                       
            field[i] = s[i];
            //*s_field = *s_field+1;        
        }               
        i++;
    }
    s_field = field;            
    r_record.push_back(s_field);
} 

void getLine(FILE *fp)
{
    char c;
    int j=0;    
    table.clear();
    l1:while ( (c = getc(fp)) != EOF ) 
    {  
        if( c != '\n' )
        {
           line[j] = c;

        }
        j++;
    }   
    getField(line);
    table.push_back(r_record);
    if(c != EOF)
        goto l1;                        
    cout<<table.size(); 
} 

int main()
{
    double total_time;  
    clock_t start, end;
    start = clock();//time count starts 
    FILE *f1;   
    f1 = fopen("somesamplefile.txt","r+");      
    getLine(f1); 

    end = clock();//time count stops 
    total_time = ((double) (end - start)) / CLOCKS_PER_SEC; //calulate total time
    printf("\nTime taken to print  %f\n", total_time);

    return 0;
}

2 个答案:

答案 0 :(得分:0)

我会注意@MattMcNabb关于在为字符串中的单个字符赋值之前检查限制的注释。

此外,您field尚未终止getField。没有它,声明

    s_field = field;

可能会超出范围访问数据并导致未定义的行为。

void getField(char s[LIMIT])
{
    // **** CORRECTION *****
    // I am guessing you meant to use field[FIELD].
    // char field[LIMIT];      
    char field[FIELD];

    int i=0;
    r_record.clear();

    // **** CORRECTION *****
    // Add a check to stop going beyond the limits of the array.
    // while(s[i]  != '\n')
    while( i < FIELD-1 && s[i]  != '\n')
    {   
        if (s[i] != '\t' )
        {                                                       
            field[i] = s[i];
            //*s_field = *s_field+1;        
        }               
        i++;
    }

    // **** CORRECTION *****
    // Add this
    field[i] = '\0';

    s_field = field;            
    r_record.push_back(s_field);
} 

另外,我认为您打算使用

char line[LIMIT];   

而不是

char line[FIELD];   

答案 1 :(得分:0)

衷心001 25 city1 衷心的002 26 city1 衷心003 27 city1 衷心004 25 city1 衷心005 28 city1 衷心006 29 city1 衷心007 30 city1 heartly 001 25 city1 衷心的002 26 city1 衷心003 27 city1

在文本中有制表符分隔格式,应该显示不正确

修正后的程序

#include <iostream>
#include <cstring>
#include <cstdlib>
#include <fstream>
#include <string>
#include <cctype>
#include <cstdio>
#include <ctime>
#include <vector>
#include <sstream>
#include <algorithm>
#include <iterator>
#include <sys/stat.h>
#include <iterator>
#include <exception>
#include <dirent.h>
#include <unistd.h>
#include <map>
#include <unordered_map>
#include <sys/timeb.h>
#include <stdexcept>                                                     // std::out_of_range
#include <time.h>
#define LIMIT 22
#define FIELD 8

using namespace std;
typedef vector <string> record_t;
typedef vector <record_t> table_t;
char line[LIMIT];   
string s_field;
table_t table;
record_t r_record;

vector <string>::iterator t_record;

void getField(char s[LIMIT])
{
    // **** CORRECTION *****
    // I am guessing you meant to use field[FIELD].
    // char field[LIMIT];      
    char field[FIELD];

    int i=0;
    r_record.clear();

    // **** CORRECTION *****
    // Add a check to stop going beyond the limits of the array.
    // while(s[i]  != '\n')
    while( i < FIELD-1 && s[i]  != '\n')
    {   
        if (s[i] != '\t' )
        {                                                       
            field[i] = s[i];
            //*s_field = *s_field+1;        
        }               
        i++;
    }

    // **** CORRECTION *****
    // Add this
    field[i] = '\0';

    s_field = field;            
    r_record.push_back(s_field);    
} 

void getLine(FILE *fp)
{
    char c;
    int j=0;    
    table.clear();
    l1:while ( j < LIMIT-1 ) 
    {  
        c = getc(fp);
        if( c != '\n' )
        {
           line[j] = c;
            j++;
        }                 
    }   
    line[j] = '\0';
    if( c!= EOF )    
    {       
        getField(line);
        table.push_back(r_record);
        j=0;
        goto l1;
    }

} 

int main()
{
    double total_time;  
    clock_t start, end;
    start = clock();//time count starts 
    FILE *f1;   
    f1 = fopen("somesamplefile.txt","r+");      
    getLine(f1); 
    for(t_record = r_record.begin(); t_record != r_record.end(); ++t_record )
    {
      cout <<*t_record <<endl;
    }
    cout<<table.size(); 
    end = clock();//time count stops 
    total_time = ((double) (end - start)) / CLOCKS_PER_SEC; //calulate total time
    printf("\nTime taken to print  %f\n", total_time);

    return 0;
}