2013-02-15 3 views
-3

문자열과 벡터 대신 동적으로 할당 된 2 차원 문자 배열을 사용해야하는 프로그래밍 할당이 있습니다. 두 클래스가 있습니다 : char 배열에 대한 포인터를 보유하는 Word 및 Word 배열에 대한 포인터를 보유하는 WordList.배열 내의 객체에서 함수를 호출 할 때 세그먼트 오류가 발생했습니다.

분할 폴트 코드 섹션에서 제공 :

FOUT은 ofstream 객체가
for(int i=0; i<listLength; i++) 
    fout << "Word " << i << (wordList[i])->getWord() << endl; 

은 단어 목록은 ** 객체 워드이고 getWord()는 워드 오브젝트의 멤버 함수이다. 문제는 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이 아닌가요? 또한 배열과 그 멤버를 할당하는 방법을 보여주십시오. –

+3

더 많은 코드를 제공해 주실 수 있습니까? 이상적으로 [sscce] (http://sscce.org/) – simonc

+0

@JoachimPileborg 긍정적 인 wordList [i]는 다른 함수에서 액세스 할 수 있으므로 null이 아닙니다. –

답변

0

주 지역 변수로 생성자 포인트 blankPtr는,이 포인터가 유효하지 않습니다 일단 생성자가 반환하면. 또한 parse 함수에서 문자열에 대한 포인터를 삭제하면 해당 포인터도 무효가됩니다. 뿐만 아니라 실제로 Word 개체 포인터를 삭제합니다. 즉, 배열에 잘못된 포인터가 있습니다.

Word 생성자 내에 복사본을 만들지 않으면 (포인터를 복사하지 않고 새 메모리를 할당하는 경우) Word 개체에 불법적 인 포인터가 포함되어 정의되지 않은 동작이 발생할 수 있습니다.

정의되지 않은 동작은 한 번 작동하지만 다른 동작은 작동하지 않을 수 있으므로 까다로운 작업입니다. WordList::Wordlist에서

1

는 :

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이 인수를 복사하는 경우에만 가능합니다. 그렇지 않으면 아무 것도 사용할 수없는 포인터를 보유하게됩니다.

핸드 롤 할당 및 원시 포인터로 작업하려면 어떤 개체가 어떤 메모리를 소유하고 있으며 할당하고 해제해야하는지에 대한 명확한 정책을 설정해야합니다.
가장 좋은시기는 키보드를 터치하기 전입니다.

관련 문제