在 C++ 中 memcpy'ing std::string

memcpy'ing std::string in C++

对于 Eigen 矩阵库,有人提交了以下问题:

https://forum.kde.org/viewtopic.php?f=74&t=140169

据我了解,问题是您不能对两个 std::strings.

进行基于 memcpy 的交换

在这里进行 memcpy 似乎并不可取,但我也不明白记者指出的问题。

似乎如果 std::string 在概念上是:

class string
{
    union
    {
        class heap_str_
        {
            char* str_;
            size_t len_;
        }
        char small_str[16];
    }

};

我认为这两个在 memcpy 下都可以(?)(无法承受所有权问题,我想 'okay' 交换)。

我在这里错过了什么?

该错误包含以下详细信息:

internal data was not invariant of the storage location (storing an offset into this).

这会立即推翻你的假设。

结构可能看起来大致如下:

class string
{
    char* str_;
    union
    {
        size_t len_;
        char small_str[16];
    };
};

这样就可以访问 str_,而无需在每次访问时检查 SSO。

问题是 SSO 对 memcpy 不安全,因为指向数据的指针通常被重定向到对象堆栈部分内的内部缓冲区。因此,当对象被复制到新位置时,指针仍然指向旧对象内部的(旧的,可能不再有效的)位置。

当然,std::string(以及所有非 POD 类型)通常不应首先 memcpy,尤其是当涉及堆分配时,因为它有风险,在至少,双重删除或堆损坏。

所以不,你不应该,永远,永远 memcpy 非 POD。即使你认为你 should/need 到。使用 std::copy 或想出其他办法。