2013-02-15 76 views
-3

我有一個編程任務,要求我們使用動態分配的二維char數組代替字符串和向量。我有兩個類:包含指向char數組的指針的Word,以及包含指向Word數組的指針的WordList。從調用數組中的對象的函數時發生分段錯誤

段故障來自這部分代碼:

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

其中Fout爲使用ofstream對象,單詞表是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; 
} 
+2

你確定'wordList [i]'不爲null嗎?另外,請說明如何分配數組及其成員。 – 2013-02-15 10:00:37

+3

你能提供更多的代碼嗎?理想情況下,[sscce](http://sscce.org/) – simonc 2013-02-15 10:00:57

+0

@JoachimPileborg正面wordList [i]不爲null,因爲我可以訪問來自不同的函數 – 2013-02-15 10:03:37

回答

0

注意blankPtr在構造函數中指向一個局部變量,這個指針將無效一旦構造函數返回。另外,在parse函數中,您刪除了指向該字符串的指針,並使該指針無效。不僅如此,你實際上刪除了Word對象指針,這意味着你的數組中有一個非法指針。

除非在Word構造函數中創建副本(不只是複製指針,而是分配新內存),否則Word對象將包含導致未定義行爲的非法指針。

未定義的行爲是棘手的,因爲它看起來可以工作一次,而不是另一次。

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複製其參數時纔可以。否則,它現在擁有一個指針,你不能使用任何東西。

如果你要使用手動分配和原始指針,你需要設置一個非常明確的策略,爲哪個對象擁有哪個內存並負責分配和釋放它。
在觸摸鍵盤之前,最好的時機就是這樣做。

相關問題