NoSenseEtAl
NoSenseEtAl

Reputation: 30118

Are moved from string and vector required to not own any heap memory?

I know moved from objects are in unspecified but destructible state and I know generally that means that they can own memory, file handles... But I do not know if moved from std::strings and std::vectors are allowed to own any memory.

So for example is the following function potentially leaking memory or is it fine according to C++ standard?

void f(){
    std::aligned_storage_t<sizeof(std::string), alignof(std::string)> memory;
    std::string& src = *new (&memory) std::string ("98->03->11->14->17->20");
    std::string dest(std::move(src ));
}

notes:

Upvotes: 2

Views: 106

Answers (2)

M.M
M.M

Reputation: 141638

There's nothing in the standard that requires a moved-from object to no longer own any resources. (Other than performance guarantees but I don't see them preventing such ownership in this case).

Regarding your program, see [basic.life/4]:

For an object of a class type with a non-trivial destructor, the program is not required to call the destructor explicitly before the storage which the object occupies is reused or released; however, if there is no explicit call to the destructor or if a delete-expression (5.3.5) is not used to release the storage, the destructor shall not be implicitly called and any program that depends on the side effects produced by the destructor has undefined behavior.

The part of this "any program that depends on the side effects" is not as precise wording as we like to see in a standards document, but it's usually interpreted to mean "anything other than a destructor that has no observable behaviour" . We don't know what the library implementation might have put in its destructor for vector and string (e.g. it could have debugging tracking in debug mode).

So I would say your program causes undefined behaviour by omitting the destructor call , although there is some room to debate.

Upvotes: 2

Yakk - Adam Nevraumont
Yakk - Adam Nevraumont

Reputation: 275800

No; pathological implementations are free to move-construct any specific std string as a copy, leaving the source alone, so long as the operation doesn't throw. (there must be a length beyond which this does not happen to obey O(1) guarantee).

A std vector's iterator invalidation rules are tighter; the move would have to be pathologically evil to own memory afterwards. Similarly it may not throw, even if allocation fails.

Both if these are unreasonable possibilities; but so is skipping destruction.

Upvotes: 3

Related Questions