-3

我有一个编程任务,要求我们使用动态分配的二维字符数组来代替字符串和向量。我有两个类:Word 包含指向 char 数组的指针,WordList 包含指向 Word 数组的指针。

分段错误来自这部分代码:

for(int i=0; i<listLength; i++)
    fout << "Word " << i << (wordList[i])->getWord() << endl;

其中 fout 是 ofstream 对象,wordList 是 Word** 对象,getWord() 是 Word 对象的成员函数。问题是我在 WordList 的另一个成员函数中使用了相同的 wordList[i]->getWord() 语法并获得了正确的输出。

请让我知道是否需要更多代码来正确诊断问题

更多代码:

#include <iostream>
#include <fstream>
#include <cstring>
#include <string>  
#include "Word.h"

using namespace std;

class WordList
{
public:
    int listLength_;
    Word** wordList_; 

WordList()
{   
    char blank = ' ';
    char* blankPtr = &blank;
    setListLength(1);
    wordList_ = new Word* [listLength_];
    for(int i=0; i<listLength_; i++)
    {
        wordList_[i] = new Word(blankPtr);
    }
}

void addWord(Word* word, Word** wordList, int n)
{
    Word** wl_temp = new Word* [n+1];

    for(int i=0; i<n; i++)
    {
        wl_temp[i] = wordList[i];
    }

    wl_temp[n] = word;
    delete[] wordList;
    setWordList(wl_temp);
    listLength_++;            
    cout << " " << (wordList_[n]->getWord()); //works here 
}

void parse(const char* filename)
{
    ifstream fin(filename);

    char end;
    char* tw;
    while(fin >> end)
    {
        fin.unget();
        fin.get(tw=new char[49], 49, ' ');
        Word* w = new Word(tw);
        addWord(w, getWordList(), getListLength());

        delete w;
        delete[] tw;
    }  
}

void output(const char* outfile)
{
    ofstream fout(outfile);

for(int i=1; i<=listLength_; i++)
        fout << "Word " << i << (wordList_[i])->getWord() << endl; //not here
    fout.close();
}
};

int main(int argc, char* argv[])
{
    WordList wordList;

    wordList.parse(argv[1]);
    wordList.output(argv[2]);

    return 1;   
}
4

2 回答 2

1

WordList::Wordlist

    wordList_[i] = new Word(blankPtr);

您在这里传递了一个指向局部变量的指针。

这不仅本身就是一个问题,而且“字符串”不是以零结尾的。
无论是否Word假定对象的所有权,这都会导致未定义的行为。

如果Word::Word复制它的论点,这是一个非常迂回(和错误)的写法new Word(" ")

parse

    Word* w = new Word(tw);
    addWord(w, getWordList(), getListLength());

    delete w;

您已添加w到单词列表。现在你正在delete处理它。
单词列表现在包含一个指向已释放内存的指针。取消引用它也会导致未定义的行为。

   delete[] tw;

仅当Word::Word复制其参数时才可以。否则,它现在拥有一个您不能用于任何事情的指针。

If you're going to work with hand-rolled allocation and raw pointers, you need to set a very clear policy for which object owns which memory and is responsible for allocating and releasing it.
The best time to do this is before you touch the keyboard.

于 2013-02-15T11:04:01.927 回答
0

注意blankPtr在构造函数中指向一个局部变量,一旦构造函数返回,这个指针就无效了。此外,在parse函数中删除指向字符串的指针,使该指针也无效。不仅如此,您实际上删除了Word对象指针,这意味着您的数组中现在有一个非法指针。

Word除非您在构造函数中创建副本(不仅仅是复制指针,而是分配新内存) ,否则您的Word对象将包含导致未定义行为的非法指针。

未定义的行为是棘手的,因为它似乎可以工作一次,但不能再次工作。

于 2013-02-15T10:50:37.400 回答