简体   繁体   English

C++ std::shared_ptr 调试断言失败

[英]C++ std::shared_ptr debug assertion failure

I am studying the std::share_pointer with visual studio 2019 and I wrote a program just implements swapping two integers.我正在使用 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
}

But the program showed a dialog box titled Microsoft Visual C++ Runtime Library.但该程序显示了一个名为 Microsoft Visual C++ Runtime Library 的对话框。 Here's the information of the dialog box.这是对话框的信息。

Debug Assertion Failed!
Program:
....../ConsoleApplication1.exe
File: minkernel\crts\ucrt\src\appcrt\heap\debug_heap.cpp
Line: 904

Express: _CrtIsValidHeapPointer(block)

......

Then I tried the same code with MinGW, The program was running normally.然后我用MinGW尝试了相同的代码,程序运行正常。 Did I abuse the shared_ptr?我滥用了 shared_ptr 吗?

Your problem is in this line, shared pointer requires that the data it uses be allocated on the heap, not the stack.您的问题出在这一行,共享指针要求它使用的数据分配在堆上,而不是堆栈上。 This is why the constructor takes pointers not references.这就是构造函数采用指针而不是引用的原因。

//...
std::shared_ptr<int> pa(new int{a});
std::shared_ptr<int> pb(new int{b});
//...

Note in swap1 you are swapping the ints that are contained in the shared_ptrs not the shared_ptrs themselves.请注意,在 swap1 中,您交换的是 shared_ptrs 中包含的整数,而不是 shared_ptrs 本身。

Also using std::swap to swap things works better, in general.一般来说,使用 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

This can even be used to swap the shared_ptrs, NOTE this is different than swapping their contents.这甚至可以用来交换 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

Yes, you abused it.是的,你滥用了它。

shared_ptr is useful because it automatically deletes the object it owns when necessary. shared_ptr很有用,因为它会在必要时自动删除它拥有的 object。 That's its only purpose.这是它的唯一目的。 Here, you attempt to make a shared_ptr out of a pointer to a local variable, and the object will later try to delete it.在这里,您尝试使用指向局部变量的指针创建shared_ptr ,然后 object 将尝试删除它。 Except you can't really do that, since the variable is on the stack (try calling delete &a at the end of main , you'll get the same result).除非你真的不能这样做,因为变量在堆栈上(尝试在main的末尾调用delete &a ,你会得到相同的结果)。

Normally, you would create a shared_ptr usingstd::make_shared .通常,您将使用std::make_shared创建一个shared_ptr That way, the raw pointer does not have to go through your hands at all.这样,原始指针根本不必通过您的手指向 go。

This post advises caution against initializing shared pointers with the same raw pointer (and against directly initilaizing the class with a raw pointer variable as well). 这篇文章建议谨慎使用相同的原始指针初始化共享指针(也不要使用原始指针变量直接初始化 class)。 I suggest std::make_shared as it is a standard way to make these.我建议std::make_shared因为它是制作这些的标准方法。 To resolve the error, you can initialize pa and pb as follows:要解决该错误,您可以按如下方式初始化 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM