-1

Given that an array name is implicitly converted to a pointer, how do I copy a position of said array into a std::shared_ptr?

#include <iostream>
#include <memory>

int main() {
    int arr[3] = {7, 8, 9};
    std::cout << arr[0] << std::endl; //-> 7

    std::shared_ptr<int> arr_ptr(arr); // Core dumped
    std::shared_ptr<int> arr_ptr(&arr[0]); // Core dumped

    std::cout << std::endl;
    return 0;
}

This confuses me, because there is a legal constructor from a raw pointer in the specification:

template <class U> explicit shared_ptr (U* p);

Why can't I create a shared_ptr to this array position?

Ref: http://www.cplusplus.com/reference/memory/shared_ptr/shared_ptr/

Thx Keith :^)

user3386109
  • 34,287
  • 7
  • 49
  • 68
kmiklas
  • 13,085
  • 22
  • 67
  • 103
  • 2
    Don't do that. `shared_ptr` deletes the memory. You don't delete a statically defined array. – Michael Albers Jan 19 '17 at 03:26
  • 1
    *"Given that an array name is a pointer"* No it's not. – Baum mit Augen Jan 19 '17 at 03:30
  • @BaummitAugen How would you phrase that part of the question? – user3386109 Jan 19 '17 at 03:31
  • 1
    @user3386109 Arrays can be implicitly converted or decay to pointers, but they are not pointers themselves. – Baum mit Augen Jan 19 '17 at 03:32
  • 3
    Side-note: Even if you dynamically allocated the array memory with `new`, [`shared_ptr` must be customized to make it call `delete[]` properly instead of `delete`](http://stackoverflow.com/a/13062069/364696), so this is doubly-wrong. – ShadowRanger Jan 19 '17 at 03:33
  • 2
    Given that `std::shared_ptr` implies ownership, why do you try to make one from the address of something with automatic storage duration to begin with? – Baum mit Augen Jan 19 '17 at 03:34
  • Perhaps a better question (for a different thread) would be if/how smart pointers can be used with raw pointers that can't be fully converted at this time. – kmiklas Jan 19 '17 at 03:40
  • Note some APIs may force you into using shared pointers when you'd rather stay static. Use [`std::make_shared`](http://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared) to satisfy those folk. – user4581301 Jan 19 '17 at 04:17

2 Answers2

2

arr is statically allocated on the stack, not dynamically with new. Once the shared pointer exits scope, it will attempt to call delete on that pointer. Since the pointer references memory that was not allocated with new, the results are undefined.

std::shared_ptr<> for all intents and purposes is used for managing ownership of memory, which would otherwise be tedious to do manually. In this case, the compiler automatically manages the memory using stack frames.

Austin Brunkhorst
  • 20,704
  • 6
  • 47
  • 61
2

shared_ptr<> does something what we call in C++ as RAII. It owns up the memory and tries to clean when getting out of scope.

An example with placement new will explain what is happening over here

int main()
{
    // Allocate memory in stack
    char memory[4];
    // use stack memory to allocate the intMem
    int *intMem = new (&memory) int;

    // delete the memory allocated in stack
    delete intMem; // Unexpected Behaviour

    return 0;
}

In your code

std::shared_ptr<int> arr_ptr(arr); // Core dumped

This line is equivalent to what we did with placement new above. The problem is not in this line. but happens at the end of main when the local variable including the shared_ptr goes out of the scope.

Daksh Gupta
  • 7,554
  • 2
  • 25
  • 36
  • So, with old code that uses raw pointers, it is best to stay with them, until the system can be refactored using smart pointers? In other words, is it a bad idea to mix raw and smart, trying to manually wrap raw as smart pointers? – kmiklas Jan 19 '17 at 04:51
  • @Kmiklas I generally avoid having generic rules or statements in programming. But your statement is valid in most of the cases. In C++11 onward, the best way to create is using make_shared() – Daksh Gupta Jan 19 '17 at 05:08