在测试中使用 unique_ptr 时出现无效指针错误
Posted
技术标签:
【中文标题】在测试中使用 unique_ptr 时出现无效指针错误【英文标题】:Invalid pointer error when using unique_ptr in tests 【发布时间】: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
。
【参考方案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
的全部目的。因此,如果您没有通过new
或make_unique
创建指针,则不要将其存储在unique_ptr
中。
我不认为将数据复制到 unique_ptr 会解决问题。我收到此错误:double free or corruption (fasttop): 0xb87b73a0
,无论我是否复制数据。仅这一行 auto testBytesPtr = std::make_unique<uint8_t[]>(...);
就给了我错误。
那行是无害的,它只是创建了一个拥有一块新内存的 unique_ptr。但是.reset(somelocal)
不好。以上是关于在测试中使用 unique_ptr 时出现无效指针错误的主要内容,如果未能解决你的问题,请参考以下文章
free():在 unique_ptr 上使用 get() 而不是 release() 时指针无效