Reputation: 310822
I'm using a C library (libwebsockets) which allows some user-data for each client. The library owns this memory, passes it as a void*
, and my code reinterpret_cast
's it to my user-data type.
I'm trying to add a std::string
field to this class and am now seeing segfaults. Calling functions on this class causes errors, which is fair enough as it's likely backed by uninitialised memory.
How can I initialise that memory> I've tried assigning (the assignment operator segfaults) and calling various functions such as clear
. I'm guessing there's a C++ mechanism for this.
Furthermore, how can the destructor be called when the string is no longer needed?
Upvotes: 1
Views: 173
Reputation: 168988
Assuming that you have a type something like this:
class MyType
{
std::string foo;
std::string bar;
};
And assuming that the void *
points to an uninitialized allocation of at least sizeof(MyType)
bytes, then you can construct it (and all contained objects) using placement new syntax:
void init_callback(void * ptr) {
new (ptr) MyType();
}
Similarly, you can destruct your type (which will destruct all contained objects) by calling the destructor directly.
void destroy_callback(void * ptr) {
MyType * mine = reinterpret_cast<MyType *>(ptr);
mine->~MyType();
}
Generally you don't call destructors directly, but you have to because you can't safely delete
the pointer. The rule "every new
should have one delete
" has an analog in this situation: "every placement-new should have one explicit call to the destructor."
Upvotes: 2
Reputation: 254431
You can use placement-new to create an object in the provided memory:
std::string * s = new(memory) std::string;
and call the destructor to destroy it before reusing or releasing the memory:
s->std::string::~string();
If you find that a bit of a mouthful, then using std::string;
will reduce it to s->~string();
Upvotes: 1