1

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?

ZSY-ARCH
  • 83
  • 1
  • 7
  • 3
    You are using a shared_ptr to manage an automatic storage variable. Hilarity and hijinks ensue. – Eljay Mar 21 '21 at 13:26
  • Does this answer your question? [Why do I get \_CrtIsValidHeapPointer(block) and/or is\_block\_type\_valid(header->\_block\_use) assertions?](https://stackoverflow.com/questions/64418624/why-do-i-get-crtisvalidheappointerblock-and-or-is-block-type-validheader-b) – ead Jul 11 '21 at 20:28

3 Answers3

2

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
ceorron
  • 1,230
  • 1
  • 17
  • 28
1

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.

IWonderWhatThisAPIDoes
  • 1,000
  • 1
  • 4
  • 14
1

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);