0

These lines of code are giving me the error: free() double free detected in tcache 2 when I attempt to run the program. If i remove the final line, there is no error. append_new is a method that searches the array within item_vec and adds "initialString" to the end of the array. The method append_new has been tested in other programs. Could someone please explain the reason for this error and how to fix?

class item_vec {
    // Create private set of variables 
private:
    int strSize;
    int strCapacity;
    string* arr;

// Define functions in public
public:

    item_vec()
        : strSize(0), strCapacity(10)
    {
        arr = new string[strCapacity];
    }

    item_vec(int n, string s)
        : strSize(n), strCapacity(2 * n + 1)  // initializer list
    {
        // Check for out of bounds error
        if (n < 0) {
            cmpt::error("str_vec(int n, string s): n must be 0 or greater");
        }
        // make array and populate with string s
        arr = new string[strCapacity];
        for (int i = 0; i < strSize; i++) {
            arr[i] = s;
        }
    }

    int size() const {
        return strSize;
    }

    void append_new(string s) {
        // Variable to track if string is already present
        bool hasString = false;
        // Iterate through and update if string found
        for (int i = 0; i < strSize; i++) {
            if (arr[i] == s) {
                hasString = true;
            }
        }
        // If string isnt found append to end
        if (hasString == false) {

            // Make new copy array and replace old if no space
            if (strSize >= strCapacity) {
                strCapacity *= 2;
                string* new_arr = new string[strCapacity];

                for (int i = 0; i < strSize; i++) {
                    new_arr[i] = arr[i];
                }
                delete[] arr;
                arr = new_arr;
                delete[] new_arr;
            }
            // Update array
            arr[strSize] = s;
            strSize++;
        }
    }

    // Make destructor
    ~item_vec() {
        delete[] arr;
    }
};
user4581301
  • 33,082
  • 7
  • 33
  • 54
tg8
  • 29
  • 6
  • Bug's here: `delete[] new_arr;` You don't want to delete the new array. You just assigned it to `arr`, so what's `arr` gonna point at? – user4581301 Feb 11 '22 at 00:49
  • wow, thank you that was an easy mistake. I have a separate program, where this type of error never appeared whilst the function was defined the exact same way. – tg8 Feb 11 '22 at 00:55
  • That's [Undefined Behaviour](https://en.cppreference.com/w/cpp/language/ub) for you. Sometimes the program keeps going and looks like everything is OK. [Then this happens](https://www.youtube.com/watch?v=73wMnU7xbwE). You can bet that demonstration worked many times before Bill Gates was willing to get up on stage in front of cameras. – user4581301 Feb 11 '22 at 00:58
  • 1
    @tg8 *The method append_new has been tested in other programs* -- Even with the fix others have suggested, your class is still very easily broken: `int main() { item_vec v1; item_vec v2 = v1; }`. You now have a double-delete error after `main` returns. Read up on the [rule of 3](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). Until you make those changes, using `item_vec` in any program is not safe, as shown by that simple 2-line program having issues. – PaulMcKenzie Feb 11 '22 at 01:24

1 Answers1

0

In append_new after the old array has been copied into the new array we find

            delete[] arr; // free the old array. Good. No leak
            arr = new_arr; // point at the new array
            delete[] new_arr; // Whoooaaa! arr's pointing at that!

The program will be broken as soon as the now-deleteed array at arr is used. The program may may stagger on, mortally wounded, for a while after that, and it looks like it makes it to the next delete[] arr; where the program notices the array's already been deleteed and crashes to make sure you also know about the mistake, but it's no longer going to function correctly and the error could manifest in any manner of strange and unexpected ways at any time.

Solution: Remove

            delete[] new_arr;
user4581301
  • 33,082
  • 7
  • 33
  • 54