They each do a different thing.
1.
T a_data;
std::shared_ptr<T> my_pointer(new T);
*my_pointer = a_data;
Here, a new object (call it n
) of type T
will be allocated, managed by my_pointer
. Then, object a_data
will be copy-assigned into n
.
2.
memcpy(&my_pointer, a_data, sizeof(T)); // I assume you meant a_data here, not data
That's total nonsense - tha's overwriting the shared_ptr
itself with the contents of a_data
. Undefined behaviour at its finest (expect a crash or memory corruption).
Perhaps you actually meant my_pointer.get()
instead of &my_pointer
(that is, you wanted to copy into the object being pointed to)? If that's the case, it can work, as long as T
is trivially copyable - which means that it doesn't have non-trivial copy or move ctors, doesn't have non-trivial copy or move assignment operators, and has a trivial destructor. But why rely on that, when normal assignment (*my_pointer = a_data;
) does exactly the same for that case, and also works for non-trivially-copyable classes?
3.
my_pointer.reset(a_data);
This normally won't compile as-is, it would need to be my_pointer.reset(&a_data);
. That's disaster waiting to happen - you point my_pointer
to the automatic (= local) variable a_data
and give it ownership of that. Which means that when my_pointer
goes out of scope (actually, when the last pointer sharing ownership wiht it does), it will call the deleter, which normally calls delete
. On a_data
, which was not allocated with new
. Welcome to UB land again!
If you just need to manage a dynamically-allocated copy of a_data
with a shared_ptr
, do this:
T a_data;
std::shared_ptr<T> my_pointer(new T(a_data));
Or even better:
T a_data;
auto my_pointer = std::make_shared<T>(a_data);