Reputation: 23
I am learning C++ coming over from Objective-C / C, and for a dummy project I want to load the words from the /usr/share/dict/words
file stored on Mac OS X machines.
The idea is to load the file and get each word into an array, so I have an array
of type string
.
But I'm having trouble working correctly with dynamic memory with my arrays - using new
and delete
. I've added some of the code below, if anyone could help out...
And so I'm getting a memory error:
word:: A
word:: a
word:: aa
word:: aal
definitions(2758) malloc: *** error for object 0x100103b90: incorrect
checksum for freed object - object was
probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Load words:
string* Definition::loadWords()
{
int arrayLength = 0;
arrayOfWords = new string[arrayLength];
ifstream file;
file.open("/usr/share/dict/words");
if(file.is_open())
{
while(file.good()){
string word;
getline( file, word );
this->addWord(word, arrayOfWords, &arrayLength);
}
}
file.close();
cout << endl << "There are " << arrayLength << " words" << endl;
return arrayOfWords;
};
Add words to array:
void Definition::addWord(string newWord, string currentArray[], int* arrayLength)
{
cout << endl << "word:: " << newWord;
string *placeholderArray = new string[*arrayLength + 1];
placeholderArray[*arrayLength + 1] = newWord;
for(int i = 0; i < *arrayLength; i++){
placeholderArray[i] = currentArray[i];
}
(*arrayLength)++;
currentArray = placeholderArray;
delete [] placeholderArray;
}
Upvotes: 2
Views: 3524
Reputation: 377
currentArray = placeholderArray;
This aliases placeholderArray to currentArray. So, when you call...
delete [] placeholderArray;
.. you are deleting what currentArray is pointing to.
Upvotes: 1
Reputation: 1436
First thing I can see is this:
placeholderArray[*arrayLength + 1] = newWord;
You are adding an element past the end of the array. Arrays are indexed from 0. For example if the array length is 5 then the last element in the array is at index 4. So the line should be:
placeholderArray[*arrayLength] = newWord;
Then after that you are deleting your array with this:
currentArray = placeholderArray;
delete [] placeholderArray;
Since you are just setting currentArray to point to placeholderArray and then deleting it.
Also passing by reference is much better than passing by pointer. So rather than this:
void Definition::addWord(string newWord, string currentArray[], int* arrayLength)
Use this:
void Definition::addWord(string newWord, string currentArray[], int& arrayLength)
That you don't always have to use the * to get the value each time you want to use it.
Here's a tutorial on using references: http://www.learncpp.com/cpp-tutorial/73-passing-arguments-by-reference/
Also save yourself the time and effort and learn to use vectors and stl containers rather than arrays sooner rather than later.
Here's a tutorial for using vectors: http://www.codeguru.com/cpp/cpp/cpp_mfc/stl/article.php/c4027/C-Tutorial-A-Beginners-Guide-to-stdvector-Part-1.htm
Upvotes: 3
Reputation: 37930
Here you are simply assigning the pointer, as opposed to the values in the array:
currentArray = placeholderArray;
And here you free the space pointed to by said pointer:
delete [] placeholderArray;
The next time you to read from the freed memory space will result in undefined behavior.
Instead of using C-style arrays in C++, use std::vector
and its resize()
function. Better still, your application could simply invoke push_back()
on each newWord
, which will obviate the entire need for your addWord()
function.
Upvotes: 1