unique_ptr 中的奇怪段错误

Strange segfault in unique_ptr

在对我的代码进行小的修改后,我在 运行 时遇到了一个段错误,我不明白为什么。

这是有效的代码:

std::shared_ptr<UCHAR> myClass::myMethod(const char *str)
{
    size_t strLen = strlen(str);
    ULONG paddedLen = (strLen % this->bufferLen)
        ? ((strLen / blockSize) + 1) * this->bufferLen
        : strLen;

    std::unique_ptr<UCHAR> padded = std::make_unique<UCHAR>(paddedLen);
    memset(padded.get(), 0, paddedLen);
    memcpy(padded.get(), str, strLen);

    std::unique_ptr<UCHAR> buffer = std::make_unique<UCHAR>(this->bufferLen);
    memcpy(buffer.get(), this->buffer, this->bufferLen);

...
}

这是失败的代码:

std::shared_ptr<UCHAR> myClass::myMethod(const char *str)
{
    size_t strLen = strlen(str);
    ULONG paddedLen = (strLen % this->bufferLen)
        ? ((strLen / blockSize) + 1) * this->bufferLen
        : strLen;

    std::unique_ptr<UCHAR> padded = std::make_unique<UCHAR>(paddedLen + 1); <-- Added +1 here
    memset(padded.get(), 0, paddedLen + 1);  <--Added +1 here
    memcpy(padded.get(), str, strLen);

    std::unique_ptr<UCHAR> buffer = std::make_unique<UCHAR>(this->bufferLen);  <---Crashes here
    memcpy(buffer.get(), this->buffer, this->bufferLen);

...
}

唯一的区别是我在分配填充和内存设置时添加了 +1。

创建第二个唯一指针时崩溃。

我使用 unique_ptr 的代码/方式有什么问题吗?

有关信息:使用 QMake 和 Mingw 7.3.0 32 位 Windows 编译

std::unique_ptr<UCHAR> padded = std::make_unique<UCHAR>(paddedLen + 1);
memset(padded.get(), 0, paddedLen + 1);  <--Added +1 here
memcpy(padded.get(), str, strLen);

strLen 是否有可能大于 paddedLen?如果你的string是80,你的bufferLen是40,那么paddedLen就是0,但是现在你要分配一个长度为1的buffer,复制80个字符到里面。

std::unique_ptr<UCHAR> padded = std::make_unique<UCHAR>(paddedLen + 1); <-- Added +1 here
std::unique_ptr<UCHAR> buffer = std::make_unique<UCHAR>(this->bufferLen);  <---Crashes here

您每次分配UCHARs,其值分别为paddedLen + 1this->bufferLen。您需要长度为 paddedLen + 1this->bufferLen 元素的 arrays。您需要对数组使用 std::unique_ptrstd::make_unique() 的模板特化,例如:

auto padded = std::make_unique<UCHAR[]>(paddedLen + 1);

std::fill_n(padded.get(), paddedLen + 1, 0);
std::copy_n(str, strLen, padded.get());

auto buffer = std::make_unique<UCHAR[]>(this->bufferLen);
std::copy_n(this->buffer, this->bufferLen, buffer.get());

...

也就是说,这可以使用 std::vector 来简化:

std::vector<UCHAR> padded(paddedLen + 1, 0);
std::copy_n(str, strLen, padded.begin());

std::vector<UCHAR> buffer(this->bufferLen);
std::copy_n(this->buffer, this->bufferLen, buffer.begin());

...