Reputation: 30118
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::string
s and std::vector
s 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:
I am interested in ISO standard, I know that for most obvious
implementation src
should not be owning any memory after move
, I
am interested in "legal" status of this code.
I know code presented here is not "proper" way to code in C++, it is just an example to explain my question
Upvotes: 2
Views: 106
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
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