C ++损坏的双链表

时间:2015-12-09 18:07:52

标签: c++

我是来自Java的c ++新手,我遇到了c ++ I / O的问题。我做了一个小程序来说明我的问题。主要思想是拥有三维数组并通过读取具有特定文本格式的文本文件来初始化它的值。该文件包含级别(L)的数量,第一维度和行和列的大小(N)是第二维和第三维(数组[L] [N] [N])。

编辑:执行我的程序我使用g++ -std=c++0x program.cpp

以下是该计划:

#include <iostream>
#include <string>
#include <fstream>

using namespace std;

int num_of_stages;
int N ;
string ***stages;

void readFile(string file_name){
    string line;
    int pos;

    ifstream file (file_name);

    if (file.is_open()){

        getline (file,line);                    // L=XXX
        pos = line.find("=");
        line = line.substr(pos+1);
        num_of_stages = atoi(line.c_str());
        cout << "L=" << num_of_stages << endl;

        getline (file,line);                    // N=XXX
        pos = line.find("=");
        line = line.substr(pos+1);
        N = atoi(line.c_str());
        cout << "N=" << N << endl;      

        // setting the stages array with dimensions stages[L][N][N]
        stages = new string**[num_of_stages];
        for(int i = 0 ; i < N ; i ++){
            stages[i] = new string*[N];
            for(int j = 0 ; j < N ; j++){
                stages[i][j] = new string[N];
            }
        }

        for(int i = 0 ; i < num_of_stages ; i++){
            getline (file,line);                // Level comment
            cout << "Level " << line << endl; 
            for(int j = 0 ; j < N ; j++){
                for(int k = 0 ; k < N ; k++){
                    string currentValue ;
                    file >> currentValue;
                    stages[i][j][k] = currentValue;
                    cout << currentValue << " " ;
                }
                cout << endl;
            }
            cout << endl << endl;
            // I am guessing that this getLine() 
            // is necessary to read the end of the line
            // if I try remove it everything goes wrong
            // everytime I print the line's values is ' ' (empty)
            getline (file,line);
            // remove any string value to detect end of file        
            // so the if statement below will be true
            line.clear();
        }
        getline (file,line);                    // END OF MAZE comment
        cout << line << endl;
        if(line != "END OF MAZE"){
            cout << "Wrong file format" << endl;
            file.close();
            exit(0);
        }
        file.close();
    }else{
        cout << "Missing file with name : " << file_name << endl;
        exit(0);
    }
    // program never reach that point
    cout << "Bla bla bla" << endl;
}

int main(){
    readFile("file1.maz");
    return 0;
}

我的文件有这种文字格式:

L=5
N=16
LEVEL 1
T2 T3 T1 T2 E E T1 E E T2 T2 T1 T2 T1 T2 T1 
T1 T1 T2 T1 T2 T3 T2 T3 T2 T2 T3 T3 T1 E T3 T1 
T2 E T1 T1 T3 T2 T1 T3 E T3 T3 E T1 E T1 T1 
T1 T3 T2 E T1 T1 T2 E T2 T2 T2 T1 T3 T3 T1 T3 
E E T1 T3 T1 T3 T1 T2 T2 T1 T1 E T2 T1 T1 T3 
T2 T1 T1 T3 T3 E T2 T3 T3 T2 T1 E T3 T2 T1 T2 
T2 T1 T3 T2 T2 E T2 E E E T3 T3 T2 T3 T3 T1 
E E E T2 E E T3 E T1 T2 T1 T2 T1 T3 T3 E 
T3 T2 T1 T3 E T1 E T2 T3 T1 T2 T2 T3 T2 E T1 
T2 T3 E E T2 T2 E T3 E E T3 T1 T3 T1 E T3 
T1 T1 E T1 T1 T3 T3 T1 E T2 T3 T1 T3 T3 T3 E 
T3 T1 T1 T1 T2 T2 T3 T1 T3 T2 E T2 T1 E T1 E 
T3 E T2 E T1 T1 T3 T2 T3 T2 T3 E T3 T3 T2 T2 
T1 T1 E T3 T1 E T2 T1 T3 T1 T1 T2 T2 T2 T1 T2 
T3 E T3 T3 T3 T2 T1 T1 E E E T2 T1 T2 E T3 
T1 E T3 T2 E E T3 E E E T3 T1 E T2 T2 E 
LEVEL 2
T2 T2 T3 T2 T1 T1 T3 T3 T1 E T1 T2 T3 T2 E T1 
T1 T3 T2 E T2 E T2 T2 T3 T1 T3 T1 E T3 T3 T3 
T3 T3 T3 E T3 T3 E T3 T1 T1 T1 T2 T2 T3 T2 T1 
T2 T3 T1 T2 T1 E E T2 T1 T1 T3 T2 E T1 T2 T3 
T2 T2 T3 E T3 T3 T1 T1 E T3 T3 T2 T3 E T1 E 
T2 T3 T3 T2 E E E T2 T1 T3 E T2 T1 T3 E T1 
T3 T3 E T1 E T3 T1 T1 T3 T3 E T3 E T3 T1 T2 
T2 E T1 E T1 T3 T1 T3 E T3 T1 E T1 T3 T1 E 
T3 E E T1 T3 T2 T2 E T3 T2 T2 T1 E T1 T2 T2 
T3 T3 E E T2 T1 T3 T1 E T3 E E E E T1 E 
T3 E E T2 E E T2 T1 T2 T1 T1 T2 T3 T2 T3 T1 
T3 E T2 T3 T1 T3 T3 T2 E T1 T2 T2 T2 T2 T1 E 
T2 T3 T1 T3 T2 T3 T2 T3 T1 T1 T3 T3 T2 T2 E T3 
T3 T3 T2 T3 T1 T3 T1 T1 T2 E E T3 E T1 T2 T2 
T1 T2 T2 T2 T1 T1 T1 E T1 T2 T2 E T1 T3 T1 T3 
E T2 E E T3 T3 E T1 T1 T2 E T1 T3 E T3 T3 
LEVEL 3
T3 E T1 T3 T3 T3 T2 T3 T1 E T1 T1 T1 T2 E T1 
T1 E E T2 T1 T3 T1 E T1 T3 T3 T3 T3 T2 T1 T1 
T2 T3 T1 T2 T3 E T3 T1 T3 E T1 T3 T1 T2 E T3 
T1 T2 T1 E T2 T1 T1 T3 T2 T2 T2 T2 T3 T3 E T1 
T3 T2 T3 E T3 T1 T1 T2 E T2 E T3 T1 T1 E T1 
T3 E T2 T3 T2 E E T2 T1 E T1 E T2 E T3 T3 
E T2 T1 T3 E T1 E E T3 T1 T1 T3 T2 T1 E E 
T1 T3 T2 T3 T1 T2 T1 E T2 T3 T3 T1 T3 T2 T3 T2 
E T2 T1 T1 E T1 T2 T3 E T2 T1 T3 E T3 E T2 
T3 E T1 T3 T2 E T1 T1 E T2 T3 T3 T3 T2 E E 
T2 E E T2 T3 T3 T1 T2 T1 T2 T1 T3 T2 T2 T2 T2 
T1 E T2 T3 T2 E T2 T2 T1 T2 T1 E T2 E T2 T3 
T2 E T1 E E T1 T3 T1 E T1 E T1 T1 E T2 T2 
T2 T3 T3 T1 E T1 T1 E T1 T3 T3 T3 E T2 T2 E 
T2 T1 T1 T1 T2 E T1 T3 T3 T3 T2 E T3 E T2 E 
E T2 T1 T2 E T1 T3 T1 T3 T1 T3 T2 T1 T1 E T3 
LEVEL 4
E E E T1 T2 T1 T1 E T1 T3 T2 E E T1 T3 T2 
T2 T2 E T3 T3 E E T1 T3 E E T1 T2 T3 T2 E 
T2 T3 T3 T3 T3 E T2 T2 T1 T1 T1 T2 T3 E T2 T1 
T2 T1 E T2 T3 T3 T3 E T1 T3 T2 T2 T2 T1 E T3 
T3 T2 T3 E T2 E T2 E T2 T1 T1 T3 E T2 E T2 
E T1 T1 T1 E E E T2 T1 T1 T3 T1 T2 E T3 T3 
E T3 E T1 E T2 T2 T1 T2 E T3 T3 T3 T1 T3 T3 
E T2 T1 T1 T2 T2 T3 E E T1 T3 T3 T3 T1 T2 E 
T3 T3 T2 E T3 T2 E T1 T2 E E T2 T2 T1 E E 
T3 E E T2 T3 T2 T1 T2 T3 T1 E T1 T3 T2 T1 T2 
E T2 T1 T2 T3 T2 E T3 T3 T1 E T3 T3 T3 T3 T1 
E T2 T1 T1 T1 T3 E T2 E T3 T1 T1 T2 T2 E E 
T3 T3 T3 T2 E T1 T1 T3 T3 T3 E T3 T3 T3 T1 T1 
T2 T1 T1 T2 E E E T3 T1 T3 T3 T1 E E T1 T2 
T1 T2 T2 E T2 T1 T3 T3 T1 T1 T2 T3 T3 T1 T2 T1 
T1 T2 T1 E T1 T3 T2 T1 T1 T2 E E T1 E T3 T1 
LEVEL 5
T1 T1 T3 T1 T2 T3 E T2 T2 T1 T3 T2 T2 E T1 T1 
T3 E T3 E T2 T1 T1 T3 T2 T3 T1 T1 T3 T2 T3 T1 
T2 T3 T1 T2 T2 E T1 T3 E T2 T2 T2 T3 T3 T2 T2 
T1 E T1 T1 T2 T1 T3 E T3 E T1 T1 T3 T3 T1 T3 
T1 T1 T3 T2 T2 E E E E T2 E T1 T1 T2 E T2 
E T2 E E T3 E T1 E E T1 T3 T2 E E T2 E 
T2 T3 T3 E T3 T2 T2 T3 T1 E E E T3 T2 T3 T2 
T1 T1 T1 T1 E T2 E E T1 T3 T2 T1 T3 E E E 
T1 T1 E T1 T3 E E E T1 T1 T1 T3 T1 T2 T3 T3 
T2 T2 T3 T3 E T2 T1 T3 T2 T1 T3 T1 T1 T2 T3 E 
T3 T1 T3 T3 T3 E T1 T1 E T3 T2 E T2 T2 E T1 
T1 T3 E T1 T2 T2 T2 T2 T3 T3 E E T3 T1 T1 T2 
T1 E E T3 T2 T2 T1 T2 T2 T2 T2 T1 T3 T3 T3 E 
T3 E E T2 T1 T3 T1 T2 E E T3 E T3 T2 T1 E 
T1 T3 T1 T3 T2 E E T2 T2 T2 E T1 T2 E T1 T1 
T2 T3 T1 T3 T1 T1 T2 T2 E T1 T2 T1 T2 E E T1 
END OF MAZE

当我使用上面的文件示例执行我的程序时,我收到此错误:

Error in `./a.out': corrupted double-linked list: 0x0000000001174280 ***

这是gdb的回溯:

(gdb) backtrace
#0  0x00007ffff7531cc9 in __GI_raise (sig=sig@entry=6)
    at ../nptl/sysdeps/unix/sysv/linux/raise.c:56
#1  0x00007ffff75350d8 in __GI_abort () at abort.c:89
#2  0x00007ffff756e394 in __libc_message (do_abort=do_abort@entry=1, 
    fmt=fmt@entry=0x7ffff767cb28 "*** Error in `%s': %s: 0x%s ***\n")
    at ../sysdeps/posix/libc_fatal.c:175
#3  0x00007ffff75790f7 in malloc_printerr (action=<optimized out>, 
    str=0x7ffff7678bfc "corrupted double-linked list", ptr=<optimized out>)
    at malloc.c:4996
#4  0x00007ffff757a7a7 in _int_free (av=0x7ffff78b9760 <main_arena>, p=<optimized out>, 
    have_lock=0) at malloc.c:3996
#5  0x00007ffff7b898be in std::basic_filebuf<char, std::char_traits<char> >::_M_destroy_internal_buffer() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#6  0x00007ffff7b89d47 in std::basic_filebuf<char, std::char_traits<char> >::close() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#7  0x00007ffff7b8b3ad in std::basic_ifstream<char, std::char_traits<char> >::close() ()
   from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#8  0x00000000004018b9 in readFile(std::string) ()
#9  0x0000000000401a3d in main ()

我已经看到关于这个当前问题的其他帖子,其中一些是关于退出数组索引,但我已经测试了一切,我总是在内线。我读文件的方式有问题吗? 我希望这不是一个愚蠢的问题。 提前谢谢。

1 个答案:

答案 0 :(得分:4)

你出界了:

stages = new string**[num_of_stages];
    for(int i = 0 ; i < N ; i ++) {
        stages[i] = new string*[N];

如果您正在通过数组访问num_of_stages < N

您应该使用std::vector而不是处理原始指针并自己使用new/delete。它有一个at函数,可以检查边界。