从数组中的对象调用函数时出现分段错误

时间:2013-02-15 09:58:57

标签: c++ pointers segmentation-fault

我有一个编程任务,要求我们使用动态分配的二维char数组代替字符串和向量。我有两个类: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] - &gt; 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;   
}

2 个答案:

答案 0 :(得分: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复制其参数时才可以。否则它现在拥有一个不允许用于任何事情的指针。

如果您要使用手动分配和原始指针,您需要为哪个对象拥有哪个内存并负责分配和释放它设置一个非常明确的策略。
最好的时间是在你触摸键盘之前。

答案 1 :(得分:0)

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

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

未定义的行为很棘手,因为它似乎可以工作一次,而不是另一次。