Reputation: 85
I am studying the std::share_pointer with visual studio 2019 and I wrote a program just implements swapping two integers.
#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. 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. Did I abuse the shared_ptr?
Upvotes: 1
Views: 737
Reputation: 1268
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.
Also using std::swap to swap things works better, in general.
//...
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.
//...
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
Upvotes: 2
Reputation: 21
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). I suggest std::make_shared as it is a standard way to make these. To resolve the error, you can initialize pa and pb as follows:
std::shared_ptr<int> pa = std::make_shared<int>(a);
std::shared_ptr<int> pb = std::make_shared<int>(b);
Upvotes: 1
Reputation: 1048
Yes, you abused it.
shared_ptr
is useful because it automatically deletes the object it owns when necessary. 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. 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).
Normally, you would create a shared_ptr
using std::make_shared
. That way, the raw pointer does not have to go through your hands at all.
Upvotes: 1