Using std::vector<> and std::shared_ptr<> should cause error

283 views Asked by At

Here is my code of what I am doing :

#include <iostream>
#include <vector>
#include <memory>
using namespace std;

int main()
{
  vector<int> ar = {1};

  shared_ptr<int> sp(&ar[0]);

  cout<<*sp<<endl; // ---- [1]

  ar[0] = 10;

  cout<<*sp<<endl; // ---- [2]

  ar.clear();

  cout<<*sp<<endl; // ---- [3]



  return 0;
}

The output is coming to be :

1
10
10

Instead of cout at [3] I think, there should be any error at runtime, since the the object to be accessed is already deleted. How it is printing 10 in [3]? Or should I use any g++ flag, I am just using g++ -std=c++14 a1.cpp && ./a.out

EDIT: On running on Coliru I found out that clang++ is giving

`*** glibc detected *** ./a.out: double free or corruption (fasttop):     0x0000000002138010 ***`

But g++ is not Coliru.

3

There are 3 answers

0
Jerry Coffin On BEST ANSWER

You're pretty much bypassing anything that would guarantee a run-time error when you try to access outside the current bounds of the vector.

If you want the bounds checked, you might consider something like this instead:

std::vector<int> ar { 1 };

std::cout << ar.at(0); // no problem

ar.clear();

std::cout << ar.at(0); // guaranteed to throw an exception

A shared_ptr is for shared ownership of an object, so the object will be deleted only when there's nothing left to own it. By contrast, a std::vector assumes sole ownership of all the objects it contains, so trying to refer to one of them with a shared_ptr leads only to problems.

On the other hand, the fact that with gcc this manages to exit without a (visible) sign of the problem doesn't technically qualify as a bug in the compiler. At the end of the scope, the shared_ptr and the std::vector will both attempt to free the int to which the shared_ptr refers--but there's no requirement that doing so leads to an error message (officially that's a quality of implementation issue, though I'd certainly agree that showing the message is better than not).

1
Steephen On

It is an undefined behavior. It may or may not print 10.

std::vector::clear() deleted the object and reallocation is not guaranteed. So system may not reuse that memory, so you may get old value as result if you access the same memory location.

There is an interesting observation, if you check std::shared_ptr::use_cout() after std::vector::clear() operation, you could see answer 1.

  vector<int> ar = {1};

  shared_ptr<int> sp(&ar[0]);

  cout<<*sp<<"\n"; // ---- [1]

  ar[0] = 10;

  cout<<*sp<<"\n"; // ---- [2]

  ar.clear();
  cout<< sp.use_count()<<"\n";

  cout<<*sp<<endl; // ---- [3]

Output

1
10
1
10
1
David Rodríguez - dribeas On

There are a couple of things wrong in your code. The most obvious one is that you are creating a shared_ptr to manage an object that is already managed by the vector and will most probably get a double delete at the end of main.

The other problem is that you have a pointer to an object and use it after the object has been removed, since std::vector<int>::clear does not deallocate the memory you are hitting memory that is still managed by the vector and that's why it does not explode, but the object is not there any more, and you should not be accessing it. If instead of a int it had been a std::string the program may have crashed (it may also not have crashed, that is the nature of undefined behavior)