-1

I have a class DLXMatrix with constructor delegation. it as a simple constructor:

DLXMatrix::DLXMatrix(int nb_col);

And another more advanced one which is currently:

DLXMatrix::DLXMatrix(int nb_col, const std::vector<std::vector<int>> &rows)
    : DLXMatrix(nb_col) {
    for (const auto &r : rows)   // TODO : cleanup if an exception is raised
        add_row_sparse(r);
}

However, depending on the input, the call to add_row_sparse(r) may raise a std::out_of_range exception.

I understand that if I simply let the exception pass, I'll be leaking memory in the various attribute (typically one of the attribute is a vector)...

Note that, at this stage, this already points to a valid objects since, by delegation, it was constructed by another constructor. Therefore, I'm tempted to call the destructor as in

DLXMatrix::DLXMatrix(int nb_col, const std::vector<std::vector<int>> &rows)
    : DLXMatrix(nb_col) {
    try {
        for (const auto &r : rows)
            add_row_sparse(r);
    } catch (std::out_of_range e) {
        this->~DLXMatrix();
        throw std::out_of_range(e);
    }
} 

Unfortunately this segfaults. Am I totally out of my mind ? Should I call the destructors only on the attributes.

hivert
  • 10,579
  • 3
  • 31
  • 56
  • 4
    You wouldn't be leaking memory, unless you fail to follow RAII principles. When a constructor throws, all members and base classes that have been fully constructed prior to that point are destroyed automatically. – Igor Tandetnik Oct 24 '20 at 21:40
  • 2
    ... and since a vector releases its resources when it is destructed... The question is moot. Your segfault is due to a destructor being invoked twice. Once by you, and another when the exception is propagated. – StoryTeller - Unslander Monica Oct 24 '20 at 21:42
  • @Igor Tandetnik : I wrongly understood that they where not destructed ! Thanks ! – hivert Oct 24 '20 at 21:46

1 Answers1

1

When constructor raises, should/could I call destructor ?

No.

If exception is thrown out from a constructor, then the object never existed. It should not and cannot be destroyed.

Whether you catch in constructor or not, destructor should never be called in the constructor body.

Note that some classes may indeed need to perform cleanup if one part of the constructor has completed while another throws. In such case you do need to catch the exception then clean the partially completed construction (not by calling the destructor of the class) and then re-throw the exception.

hivert
  • 10,579
  • 3
  • 31
  • 56
eerorika
  • 232,697
  • 12
  • 197
  • 326