Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

What wording makes this double-free-causing call `std::vector<T>::clear()` in `T`'s constructor undefined behavior?

Consider the following code:

#include <string>
#include <vector>

struct Foo;

std::vector<Foo> v;

struct Foo {
    std::string s = std::string(10000, 'x');
    Foo() {}
    Foo(int) { v.clear(); }
};

int main() {
    v.resize(1);  // required, otherwise no double free
    v.reserve(2);  // optional
    v.emplace_back(10);  // causes double free
}

Here I call v.emplace_back which calls Foo(int) which calls v.clear() before emplace_back is completed. Seemingly, std::vector is unprepared for that mess and my implementation (Ubuntu 22.04’s libstdc++) results in double free: v[0] is first destroyed by clear(), and later by v‘s destructor.

What wording in any C++ standard makes the behavior of the program above undefined? I’m "simply" calling some operations on v. I don’t even access any elements of v.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

>Solution :

There is an active LWG issue 2414 to clarify reentrancy when different member functions of library objects are called. The current wording in [reentrancy] only specifies that it is implementation-defined which library functions are reentrant with regards to themselves (unless overruled by more specific rules).

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading