[英]C++ std::shared_ptr debug assertion failure
我正在使用 Visual Studio 2019 研究 std::share_pointer,我编写了一个程序来实现交换两个整数。
#include <iostream>
#include <memory>
void swap0(int* a, int* b)
{
int t = *a;
*a = *b;
*b = t;
}
void swap1(std::shared_ptr<int> a, std::shared_ptr<int> b)
{
int t = *a;
*a = *b;
*b = t;
}
int main()
{
int a = 10;
int b = 20;
std::cout << a << " " << b << std::endl; // 10 20
std::shared_ptr<int> pa(&a);
std::shared_ptr<int> pb(&b);
swap1(pa, pb);
std::cout << a << " " << b << std::endl; // 10 20
}
但该程序显示了一个名为 Microsoft Visual C++ Runtime Library 的对话框。 这是对话框的信息。
Debug Assertion Failed!
Program:
....../ConsoleApplication1.exe
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 904
Express: _CrtIsValidHeapPointer(block)
......
然后我用MinGW尝试了相同的代码,程序运行正常。 我滥用了 shared_ptr 吗?
您的问题出在这一行,共享指针要求它使用的数据分配在堆上,而不是堆栈上。 这就是构造函数采用指针而不是引用的原因。
//...
std::shared_ptr<int> pa(new int{a});
std::shared_ptr<int> pb(new int{b});
//...
请注意,在 swap1 中,您交换的是 shared_ptrs 中包含的整数,而不是 shared_ptrs 本身。
一般来说,使用 std::swap 交换东西效果更好。
//...
int a = 0;
int b = 5;
std::swap(a, b); //values of a and b are swapped, no need to roll your own swap functions
这甚至可以用来交换 shared_ptrs,注意这与交换它们的内容不同。
//...
std::shared_ptr<int> a(new int{0});
std::shared_ptr<int> b(new int{5});
std::swap(*a, *b); //swap contents of shared pointers
std::swap(a, b); //swap the shared pointers
是的,你滥用了它。
shared_ptr
很有用,因为它会在必要时自动删除它拥有的 object。 这是它的唯一目的。 在这里,您尝试使用指向局部变量的指针创建shared_ptr
,然后 object 将尝试删除它。 除非你真的不能这样做,因为变量在堆栈上(尝试在main
的末尾调用delete &a
,你会得到相同的结果)。
通常,您将使用std::make_shared
创建一个shared_ptr
。 这样,原始指针根本不必通过您的手指向 go。
这篇文章建议谨慎使用相同的原始指针初始化共享指针(也不要使用原始指针变量直接初始化 class)。 我建议std::make_shared因为它是制作这些的标准方法。 要解决该错误,您可以按如下方式初始化 pa 和 pb:
std::shared_ptr<int> pa = std::make_shared<int>(a);
std::shared_ptr<int> pb = std::make_shared<int>(b);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.