在解析相同的参数时,有时会出现段错误

时间:2016-10-28 14:30:09

标签: c++ segmentation-fault command-line-arguments

我正在编写一个C ++程序,它将从两个单独的文件中读取两个矩阵。它最终将使用这些矩阵来完成,但我现在正在解析命令行选项。这就是我如何呈现数据。

有几种不同的命令行变体:

dtype N file1 file2 file3

dtype N M L file1 file2 file3

其中dtype可以是int或double,如果只显示N,则所有矩阵都是NxN,否则matrix1是NxM,矩阵2是MxL,文件1和2包含要操作的矩阵,而file3是结果的位置存储。

我已经包含了我到目前为止所写的内容。我是C ++的新手所以请不要对你的批评过于苛刻。

现在的问题是,如果我运行此代码,它似乎是完全随机的,如果它将是段错误,我不知道是什么原因导致它。我知道在后面解决段错误可能是一个痛苦,我在这里看看其他问题,但我真的别无选择,只能请求你的帮助,因为我处于停滞状态。

要解决我使用-g选项编译g ++并通过gdb运行我的程序。我无法通过gdb复制段错误。

#include <iostream>
#include <string>
#include <string.h> 
#include <vector>
#include <fstream>
#include <typeinfo>
#include <sys/stat.h>
#include <stdexcept>

using namespace std;

inline bool exists_test(const std::string& name) {
  struct stat buffer;   
  return (stat (name.c_str(), &buffer) == 0); 
} 

int main(int argc, char const *argv[])
{

    int dtype = 0; // 0 = int; 1 = double
    int M = 0;
    int N = 0;
    int L = 0;
    const char *file1;
    const char *file2;
    const char *file3;

    for (int i=1; i<argc ; i++)
    {    
        try 
        {
            if(i==1){
                if(!((strcmp(argv[1], "int") == 0) || (strcmp(argv[1], "double") == 0))){
                    throw invalid_argument("wrong dtype");
                }else{
                    if((strcmp(argv[1], "double") == 0)){
                        dtype = 1;
                    }
                }
            }else if(i==2){
                M=stoi(argv[i]);
            }else if(i==3){
                if(!exists_test(argv[i])){
                    N=stoi(argv[i]);
                }else{
                    file1 = argv[i];
                }
            }else if(i==4){
                if(!exists_test(argv[i])){
                    L=stoi(argv[i]);
                }else{
                    file2 = argv[i];
                }
            }else if(i==5 || i==6 || i==7){
                if(!exists_test(argv[i])){
                    throw invalid_argument("no such file");
                }else{
                    if(i==6){
                        file2 = argv[i];
                    }else if(i==7){
                        file3 = argv[i];
                    }else if(strcmp(file1, argv[i]) == 0){

                    }else{
                        file1 = argv[i];
                    }
                }
            }
            continue;
        }
        catch (...)
        {
            cout << "error code 1 or this one" << endl;
            return 1;
        }
    }

    if(N==0){
        N=M;
    }
    if(L==0){
        L=M;
    }

    ifstream thisfile;

    double filler = 0;
    vector<double> readThese;
    vector< vector<double> > matrixA(4, vector<double>(3, 0));

    thisfile.open(file1);

    while (thisfile >> filler )
    { 
        readThese.push_back(filler);
    }

    thisfile.close(); 

    //for(int j = 0; j < N; j++){
    //  matrixA[0][j] = readThese[j];
    //}

    cout << matrixA[0][0] << " " << matrixA[0][1] << " " << matrixA[0][2] << " " << matrixA[0][3] << endl;
    cout << matrixA[1][0] << " " << matrixA[1][1] << " " << matrixA[1][2] << " " << matrixA[1][3] << endl;
    cout << matrixA[2][0] << " " << matrixA[2][1] << " " << matrixA[2][2] << " " << matrixA[2][3] << endl;
    cout << matrixA[3][0] << " " << matrixA[3][1] << " " << matrixA[3][2] << " " << matrixA[3][3] << endl;
}

以下显示程序的输出。它并不总是每隔一段时间就会发生一次性错误,它恰好发生在这个时候。

$ ./a.out int 3 4 1 file1 file2
0 0 0 1.63042e-322
0 0 0 1.63042e-322
0 0 0 1.63042e-322
0 0 0 5.14322e-321
$ ./a.out int 3 4 1 file1 file2
Segmentation fault (core dumped)
$ ./a.out int 3 4 1 file1 file2
0 0 0 1.63042e-322
0 0 0 1.63042e-322
0 0 0 1.63042e-322
0 0 0 5.14322e-321
$ ./a.out int 3 4 1 file1 file2
Segmentation fault (core dumped)

1 个答案:

答案 0 :(得分:2)

你宣布

matrixA(4, vector<double>(3, 0));

表示4 x 3矩阵,但随后访问第4列

cout << matrixA[0][0] << " " << matrixA[0][1] << " "\
     << matrixA[0][2] << " " << matrixA[0][3] << endl;
                                ^^^^^^^^^^^^^
                                   here

这是不存在的,所以你得到一个段错误。要测试越界,您可以使用std::vector::at()而不是std::vector::operator[],它会更慢,但如果您访问越界,则会抛出std::out_of_range异常。确保代码正常后,您可以转到operator[]

顺便说一下,将矩阵表示为vector<vector>通常是个坏主意。使用单个向量并从1D到2D坐标映射更好,反之亦然,因为单个向量可以保证元素连续存储在内存中,因此您可以获得更好的缓存局部性。