为什么 std::move 在这种情况下会导致 SEGFAULT?

Евг*_*лов 1 c++ std stdmove

为什么std::move()在这种情况下会导致SEGFAULT?

#include <iostream>

struct Message {
    std::string message;
};

Message * Message_Init(std::string message) {
    Message * m = (Message*)calloc(1, sizeof(Message));
    m->message = std::move(message);
    return m;
}

int main() {
    auto m = Message_Init("Hello");
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

PS请不要问为什么Message不以通常的 C++ 方式构造。

Fro*_*yne 6

如果你真的想做这样的事情,那么你可以使用placement new. 这允许您在已分配的内存块中构造一个对象。

一些标准容器用于placement new管理其内部对象缓冲区。

然而,它确实增加了您放置的对象的析构函数的复杂性。请阅读此处了解更多信息:“新展示位置”有什么用途?

#include <iostream>
#include <memory>

struct Message {
    std::string message;
};

Message * Message_Init(std::string message) {
    void * buf = calloc(1, sizeof(Message));
    Message * m = new (buf) Message(); // placement new
    m->message = std::move(message);
    return m;
}

int main() {
    auto m = Message_Init("Hello");
    m->~Message();  // Call the destructor explicitly
    free(m);        // Free the memory
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

正如 @selbie 所建议的,我添加了对 的析构函数的显式调用,以及对释放内存的Message调用。free我相信对的调用free实际上应该指向最初返回的缓冲区calloc,因为可能存在差异(所以free(buf)在这种情况下,但该指针在这里不可访问)。

例如,如果您为多个对象分配一个缓冲区,则调用free指向第二个对象的指针将是不正确的。