0

I have a template class that holds a pair of type T with a single constructor that accepts two parameters of type T.

template<class T>
class Foo {
    T first;
    T second;
public:
    Foo(T first, T second) {
        if (first < second) {
            this->first = first;
            this->second = second;
        } else {
            throw std::invalid_argument("First cannot be greater than second.");
        }
    }
    ...
}

and I pass two objects of my own class Bar to it in the main. Here is what Bar looks like:

class Bar{
public:
    char* name; // I am required to use c style strings.
    Gender gen;
public:
    // need this empty constructor or the compiler complains in main
    Bar() {
    }
    Bar(const char* s, Gender g);
    Bar(const Bar& bar) {
        name = bar.name;
        gen = bar.gen;
    }
    ~Bar();
}
...
// Bar's destructor looks like this:
Bar::~Bar() {
    delete[] name;
}

and this is what I do in main:

try {
    Bar b1("Mary", Gender::female);
    Bar b2("George", Gender::male);

    Foo<Bar> pair(b1, b2);

    // Foo's member's, b1 and b2 are already destroyed at this point after its constructor.
    // If I put cout statements in the destructor of Bar, they will be printed before the below cout.

    std::cout << "end of try" << std::endl;
} catch (const std::invalid_argument& ia) {
    std::cerr << "Invalid argument: " << ia.what() << std::endl;
}

My question is, why does the constructor of Foo delete first and second right after the end of its constructor? If I follow what happens with the debug tool, Foo works as planned but then deletes first and second as soon as it hits the ending parenthesis of its constructor. Why? Why did these member variable go out of scope?

littlebig
  • 23
  • 4
  • 1
    You pass `T first, T second` as values to `Foo` constructor. You should watch for the number of constructions before wondering about the number of destructions ;) – grek40 Feb 17 '21 at 07:37
  • I think you're missing a copy assignment operator in `Bar`. See [rule of three](https://en.cppreference.com/w/cpp/language/rule_of_three). – jignatius Feb 17 '21 at 07:56
  • 1
    *"I am required to use c style string"* - Then the whole point of the exercise is for you to understand how ownership of a resource (in this case the string memory) works. You don't show Bar's parameterized constructor, but if it's not allocating memory, why do release it? And if it does allocate memory, why are you letting two objects hold on to the same pointer and release it? Either way, you violate the [rule of 0/3/5](https://stackoverflow.com/q/4172722/817643). – StoryTeller - Unslander Monica Feb 17 '21 at 08:17
  • *"I am required to use c style strings"* So write your own (simplified) class string. – Jarod42 Feb 17 '21 at 09:02
  • Your copy constructor is incompatible with your destructor, leading to double free. – Jarod42 Feb 17 '21 at 09:11

0 Answers0