【问题标题】:Invalid pointer error when using unique_ptr in tests在测试中使用 unique_ptr 时出现无效指针错误
【发布时间】:2019-04-07 15:33:35
【问题描述】:

我有一个将std::unique_ptr<uint8_t[]> 作为输入并对其进行处理的方法。在我的单元测试中,

以下是我创建和初始化此参数的方式:(在 stack 上)

uint8_t testBytes[] = {1, 2, 3, 4};
std::unique_ptr<uint8_t[]> testBytesPtr = std::make_unique<uint8_t[]>(4);
testBytesPtr.reset(testBytes);

并将其传递给方法,如:

myClass.processData(std::move(testBytesPtr));

在我的单元测试结束时,我收到以下错误消息:

free():无效指针:0xbed6b8c0


这是我的单元测试的样子:

#include "gtest.h"
#include "gmock.h" // for some deps

//...

TEST(MyClassUnittests, test1) {
    // Initializing the byte array.
    uint8_t testBytes[] = {1, 2, 3, 4};
    std::unique_ptr<uint8_t[]> testBytesPtr = std::make_unique<uint8_t[]>(4);
    testBytesPtr.reset(testBytes);

    EXPECT_TRUE(myClass.processData(std::move(testBytestPtr));
}

我还应该注意,如果testBytes上初始化(例如uint8_t* testBytes = new uint8_t()),错误信息变为

双重释放或损坏(fasttop):0xb75c1e18

非常感谢任何帮助。

【问题讨论】:

  • unique_ptr 指向自动存储中的对象而不提供无操作删除器是一个坏主意。不要删除堆栈。
  • 如果不是新的,请不要删除。
  • 提供的 sn-p 是我的单元测试的全部内容。我没有明确删除任何内容,所以我不确定如何避免 implicit 删除。
  • @MatinKh unique_ptr 析构函数 delete[] 是默认保持的指针,除非您提供不同的 deleter

标签: c++ c++11 unique-ptr


【解决方案1】:

delete []-ing 不属于new []-ed 的东西,也不是你拥有的,是严重禁忌的。

看看这些行:

uint8_t testBytes[] = {1, 2, 3, 4};
std::unique_ptr<uint8_t[]> testBytesPtr = std::make_unique<uint8_t[]>(4);
testBytesPtr.reset(testBytes);

删除不相关的临时动态分配叶:

uint8_t testBytes[] = {1, 2, 3, 4};
std::unique_ptr<uint8_t[]> testBytesPtr(testBytes);

当 dtor 启动时会导致未定义行为。

诚然,您移动了一次std::unique_ptr,但这只是改变了爆炸发生的确切点。

考虑到您要测试的功能,试试这个以获得正确分配的测试数据副本:

uint8_t testBytes[] = {1, 2, 3, 4};
auto testBytesPtr = std::make_unique<uint8_t[]>(std::size(testBytes));
std::copy(std::begin(testBytes), std::end(testBytes), &testBytesPtr[0]);

【讨论】:

  • 感谢您解释问题所在。但是,我仍然不清楚如何解决这个问题。我没有明确地delete[] 任何东西,该方法只读取数据。你能澄清一下解决方案吗?
  • 添加了如何获取正确分配的测试数据副本。
  • @MatinKh: unique_ptr 在其指针被销毁时调用 delete。这就是unique_ptr 的全部目的。因此,如果您没有通过newmake_unique 创建指针,则不要将其存储在unique_ptr 中。
  • 我不认为将数据复制到 unique_ptr 会解决问题。我收到此错误:double free or corruption (fasttop): 0xb87b73a0,无论我是否复制数据。仅这一行 auto testBytesPtr = std::make_unique&lt;uint8_t[]&gt;(...); 就给了我错误。
  • 那行是无害的,它只是创建了一个拥有一块新内存的 unique_ptr。但是.reset(somelocal) 不好。
猜你喜欢
  • 2013-10-28
  • 2014-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-11
  • 2022-11-16
  • 2022-12-23
  • 1970-01-01
相关资源
最近更新 更多