2014-01-31 3 views
0

Итак, я удаляю указатели в функции resetListLine(), а затем назначая их в функции breakLine(). Я получаю базовый дамп, поэтому я думаю, что я либо удаляю указатели неправильно, либо пытаюсь использовать нулевой указатель где-то в программе. Хотя я не вижу, что проблема сама. Помощь очень ценится!Проблемы с указателями char ** words;

#include"online.h" 

//Public Funcions----------------------------------------------------- 

//creator function 
OneLine::OneLine() 
{ 
    oneLine = ""; 
    wordCount = 0; 
} 

//Destructor 
OneLine::~OneLine() 
{ 
    //if allocation has occurred than free up the words 
    if(wordCount > 0) 
    { 
     delete [] words; 
    } 
} 

istream& OneLine::readLine (istream& is) 
{ 
    //call resetLine to free up memory and reset oneLine and wordCount to empty string and zero respectively 
    char test[12] = "HEYTHERE"; 
    resetLine(); 
    //read one line from is (in this case, a file stream) and store it in oneLine 
    do 
    { 

    if(!getline(is, oneLine)) // if eof is reached 
     return is; 
    }while(oneLine.empty()); //check for empty lines 
    //return is 
    return is; 
} 

void OneLine::breakLine() 
{ 
    //create a temporary C String version of oneLine 
    char cString[800]; //There's a huge string in the file 
    char *pToken; 
    char *pToken2; 
    char cTemp[50]; 
    //store a count of the number of words in wordCount 
    int nCount = 0; 
    int i = 1; //words[0] will already be filled with a word 

    strcpy(cString, oneLine.c_str()); //make a cString copy of a C++ string 

    //use strtok to break the temporary line into words 
    //allocate enough space to hold all of the words and store them in words 
    pToken = strtok(cString, " "); 

while((pToken=strtok(NULL, " "))!= NULL) //find how many words 
{ 
     nCount++; 
} 


    strcpy(cString, oneLine.c_str()); //make a cString copy of a C++ string 

    pToken2 = strtok(cString, " "); 

    words = new char *[nCount]; //allocate enough space for words 

    strcpy(cTemp,pToken2); 
    words[0] = strdup(cTemp); 
    //free(words[0]); 
    while((pToken2=strtok(NULL, " "))!= NULL) //find how many words 
    { 
     strcpy(cTemp,pToken2); 
     words[i] = strdup(cTemp); 
     // free(words[i]);//This line was in the lab material but is causinerrors on my version of emacs 
     i++; 
    } 

    //update wordCount 
    wordCount = nCount; 
} 

void OneLine::printReverse() 
{ 
    for(int i=(wordCount); i>=0; i--) 
    { 
     cout << " " << words[i]; 
    } 

    cout << endl; 
} 

string OneLine::returnLine() 
{ 
    return oneLine; 
} 

//Private Functions------------------------------------------------------ 

void OneLine::resetLine() 
{ 
    //set oneLine to be an empty string 
    oneLine = ""; 
    //set wordCount to zero 


    //if allocation has occurred than free up the words 
if(wordCount > 0) 
    { 
     delete[] words; 
    } 

    wordCount = 0; 
} 

Главная

#include"online.h" 

int main() 
{ 
    string sCheck = ""; 
    //2. create a OneLine object 
    OneLine obj; 

    //1. create an ifstream for the file test.txt (please use this file for testing) 
    ifstream inData; 

    inData.open("test.txt"); 

    if(!inData) 
    { 
     cout << "Problem opening test.txt" << endl; 
     return 1; 
    } 

    while(!inData.eof()) 
    { 

     //3. while you can still read from the file: 
     //a. call readLine 
     obj.readLine(inData); 

     if(!inData) //This line exits the loop when eof is reached. This needs to be here since you don't want to pass eof just to other functions 
      break;  

     //b. call breakLine 
     obj.breakLine(); 

     //c. call printReverse 

     obj.printReverse(); 
    } 
    //4. close the file 
    inData.close(); 


    return 0; 
} 

Заголовочного файл

#include <string> 
#include<cstring> 
#include<iostream> 
#include<fstream> 
using namespace std; 

class OneLine 
{ 
    public: 
     OneLine(); 
     ~OneLine(); 
     void breakLine(); 
     void printReverse(); 
     istream &readLine(istream& is); 
     string returnLine(); 
    private: 
     string oneLine; 
     char **words; 
     int wordCount; 
     void resetLine(); 
}; 
+2

Вы активизировали через код в отладчике? – OldProgrammer

+6

Почему вы используете C-строки и функции библиотеки C в программе на C++? Используйте 'std :: string' и идиомы C++ вообще, и вы сэкономите много горя. –

+0

Я программист видеоигр, и я все время использую C-строки в коде C++. – Philip

ответ

2

Слово является двойным указателем. Я вижу, что вы используете

new char[] 

для инициализации исходного указателя, но тогда вам также нужно будет обновить второй слой. Так что-то вроде.

char** words 
words = new char*[10]; 
for(int i = 0; i < 10; ++i) 
{ 
    words[i] = new char[10]; 
} 

Это будет создавать 10 строк, каждая из которых содержит 10 символов.

Тогда в конце:

for(int i = 0; i < 10; ++i) 
{ 
    delete words[i]; 
} 
delete []words; 
+0

То же самое относится к деинициализации – Paranaix

+0

добавлено, хорошая точка – Philip

1

Используя что-то вроде shared_ptr может помочь разобраться с проблемой управления памятью (удаление указателя правильно/освобождения памяти). Это может быть более безопасным вариантом для вас, потому что управление будет динамичным. Короткая статья о них для вас здесь:

http://en.cppreference.com/w/cpp/memory/shared_ptr

Смежные вопросы