1

I allocated some memory (Word * wordList) for this struct:

    struct Word{
            int occurrences;
            std::string wrd;
    };

by writing:

        Word * tempList = new Word[numWords + 1];
            for(int i = 0; i < numWords; i++){
                tempList[i] = wordList[i];
            }
            delete[] wordList;
            wordList = tempList;
            tempList = 0;
            Word currWord = {1, wrd};
            wordList[numWords] = currWord;
            numWords++;

numWords is the size of wordList before and after this bit of code is called and wrd is a string passed into the method. This code runs to add a word when it isn't already present in wordList.

My problem is that when delete[] is called, the program stops working. I tried using delete to see what would happen and the program worked fine as far as I could tell. What is going on and why does delete[] cause my program to freeze?

wordList is a member of class WordsOfLength:

    class WordsOfLength{
    private:
        int numWords;
        Word * wordList;

    public:
        WordsOfLength();
        WordsOfLength(int nNumWords, Word* nWordList);
        ~WordsOfLength();
        void addWord(std::string wrd);
        std::string getWord(int frequency);
        friend void WordData::writeWordData(const char* fileName);
        friend void WordData::setWordData(const char* fileName);
    };

with constructor:

    WordsOfLength::WordsOfLength(){
        numWords = 0;
        wordList = NULL;
    }

and destructor:

    WordsOfLength::~WordsOfLength(){
        delete[] wordList;
        wordList = 0;
    }
  • 1
    The code is part of a larger class where `wordList` is a member, right? Can you show all constructors and the destructor? – Daniel Frey Oct 27 '13 at 20:13
  • Either `wordList` must point to a *valid* previous array-allocation, or it must be `nullptr`. Anything else is **undefined behavior**. – WhozCraig Oct 27 '13 at 20:16
  • sounds like you accidentally write more than you are allowed somewhere, so we'd need a little bit more context to be able to figure out what is wrong – Radu Chivu Oct 27 '13 at 20:19
  • It seems the guessing already started :) OK, here's mine: Missing copy-ctor so the member variable `wordList` is copied, freed once, then again when the copy is trying to grow. [Rule of Three/Five](http://stackoverflow.com/questions/4782757). – Daniel Frey Oct 27 '13 at 20:22
  • @DanielFrey That would be my guess as well. and I think it unlikely it will be confirmed without considerably more prodding than I've the time to deliver. Wishing you the best of luck. – WhozCraig Oct 27 '13 at 20:30
  • 2
    @WhozCraig It's just confirmed by OPs update :) OP: Read the link in my other comment about the Rule of Three/Five and implement a proper copy-ctor. – Daniel Frey Oct 27 '13 at 20:33
  • I think you two are right. There is no copy constructor and I copied the class that `wordList` is a member of several times. – user2925882 Oct 27 '13 at 20:35
  • 1
    @user2925882 that would do it. And there are a number of ways to solve it, including using a standard container that *works* with default-copying (which is how I would do it). I.e. `std::vector` With that, the words `new` and `delete` need not be in your source *at all*. Regardless, see Daniel's link. And [here is another for you](http://klmr.me/slides/modern%2Dcpp.pdf) if the desire to manually manage your own memory via new/delete every crops up again. – WhozCraig Oct 27 '13 at 20:37
  • Thank you both very much. I'm reading the first one right now. – user2925882 Oct 27 '13 at 20:41
  • Don't forget to read WhozCraig's link as well. Hilarious! Thanks for that @WhozCraig :) – Daniel Frey Oct 27 '13 at 20:49
  • Right now it's too late to use the second one's advise. I'll definitely remember it for the future though. – user2925882 Oct 27 '13 at 20:49
  • I was aware of `std::vector` when i started, but I wanted to try managing my own memory for the experience. I'd never tried it before. – user2925882 Oct 27 '13 at 20:52

1 Answers1

0

If you have not allocated wordList anywhere before the problematic line then you are trying to dealocate unallocated memory.

Igor Popov
  • 2,528
  • 14
  • 19
  • I set `wordList` to `NULL` when the object was created. The program runs through this bit of code several times with zero elemets in this bit of memory and one element in this bit of memory without visible issue. – user2925882 Oct 27 '13 at 20:20
  • Note: `nullptr` is an acceptable value to pass to `delete` and `delete[]`, effectively becoming a no-op. That said, an *indeterminate* value in `wordList`, such as failure to properly initialize to `nullptr` or a dangling pointer, is indeed undefined behavior. – WhozCraig Oct 27 '13 at 20:22
  • @user2925882 are objects of the class-type that *contains* this pointer ever copied in any way (including pass-by-value as a function parameter), and if so, did you properly implement a copy-constructor and assignment operator? I'm assuming you properly clean up the member in your class *destructor*. Update your question and post the class definition that contains this `wordList` member, including all member function declarations, constructors, etc. – WhozCraig Oct 27 '13 at 20:23
  • @WhozCraig yes, it is copied and I don't have a copy constructor or assignment operator (I don't know what that is). I'll post the code where it's copied. – user2925882 Oct 27 '13 at 20:33
  • @user2925882 See Daniel's comment and link to another question. You're not complying with what is commonly called the Rule of Three. – WhozCraig Oct 27 '13 at 20:35