convert from pointer to reference in C++ - c++

I want to create an instance of a class using new, but I want to convert to reference for further usage other than using pointer. Currently I am using this line Foo& rf = *f; to convert explicitly, it seems a bit silly. Any better and more elegant ways to create a reference variable and referring a new created instance?
Here are some code to show what I am doing,
class Foo{
public:
Foo(){
}
void printValue() {
cout << "This is Foo object " << endl;
}
};
int main() {
Foo* f = new Foo();
Foo& rf = *f;
rf.printValue();
f -> printValue();
}

You can write this:
Foo* foo = new Foo();
Foo& fooRef = *foo;
in one line:
Foo& fooRef = *new Foo();
But, be aware, you should delete your allocated memory later anyway:
delete &fooRef;
I do not suggest you write code in this way, to avoid memory leaks. Look into this answer for further details. Choose smart pointers or containers when it possible.

... convert to reference for further usage other than using pointer.
I prefer references (and avoid pointers) deep in my code. Mostly because a nullptr can have special meaning (that a reference will not) that needs some thought to confirm, the next time I review the code.
My solution is to new the bigger-than-automatic-memory object to get a pointer at the appropriate level for lifetime. I then invoke the using methods or functions with the dereferenced pointer. This keeps the pointer (at the lifetime start, such as main) as is, and later still available for the delete.
// bigData used many places
void use1_of_Data (BigData_t& bigData, Small_t& sd) {
//... do something with data
}
void use2_of_Data (BigData_t& bigData, Small_t& sd) {
//... do something with data
}
//...
void use3_of_Data (BigData_t& bigData, Small_t& sd) {
//... do something with data
}
int main(int argc, char* argv[])
{
// ...
BigData_t* bd = new BigDta_t; // (sizeof(BigData_t) > autovar space)
Small_t sd;
{
assert(nullptr != bd);
// note - bd lasts the lifetime of program
use1_of_Data (*bd, sd);
use2_of_Data (*bd, sd);
//...
use3_of_Data (*bd, sd);
}
// what's new'd in main, is deleted in main
delete bd;
}

As others have said, if the Foo instance's non-heap contents aren't so large that the Foo instance itself needs to be allocated on the heap, it is better to just use the stack:
Foo foo;
foo.printValue();
However, if it does need to be allocated on the heap for some reason, then it's dangerous to hold the only reference to it in an ordinary pointer, since if an exception gets thrown by any code, it will never be deallocated. In fact, most modern C++ guidelines advise not using ordinary pointers to own data for this reason:
Foo * fooPtr = new Foo();
doSomething(); // If an exception is thrown here, the Foo never gets deallocated!
Foo& foo = *fooPtr;
foo.printValue(); // If printValue throws an exception, the Foo never gets deallocated!
delete foo;
If you aren't familiar with this sort of problem, I suggest googling RAII ("Resource Acquisition Is Initialization") which is an crucial concept to understand when programming in C++.
An easy way to implement RAII in a case like this is through use of a smart pointer (std::shared_ptr or std::unique_ptr).
An extra reference variable can still be helpful to avoid having to use the arrow operator to call functions on the smartpointer. I disagree with some other answerers who don't see value in also binding a local reference to a value already held in a local pointer. I prefer to use references whenever possible, since when I use a reference, I can be sure that the reference isn't null (references should always refer to actual objects), while when I use a pointer (even a smart pointer) I must always be careful that my code correctly handles the case where the pointer is null. When the pointer initialization occurs close to the pointer's use, this may not be a big deal, but when they are separated, it can become hard to trace through the code to be sure the pointer can't be null. A reference makes this self-documenting.
I think that it is often useful to first ensure that a pointer or smart pointer value can't be null, and then to bind a local reference to the pointed-to value, since I can then use the reference freely without having to worry at each use about the possibility of it being null:
std::unique_ptr<Foo> fooPtr = std::make_unique<Foo>(/* Foo constructor args go here */);
doSomething(); // Now if an exception thrown here, Foo gets deallocated.
Foo& foo = *fooPtr; // We know the pointer is not null here (it just
// got returned from make_unique which
// didn't throw a bad_alloc exception) so it's
// safe to bind a reference to it here.
// Also, this reference has lifetime less than the
// smart pointer, so will never outlive it.
// .. many lines of code later ..
foo.printValue(); // No need to worry about null here.
// If exception thrown here, the unwinding of the stack
// causes fooPtr to deallocate Foo.
// No need to call delete here.
// fooPtr will automatically deallocate Foo when it goes out of scope.

If we speak about elegance, may I suggest you to use a shared_ptr?
#include <iostream>
#include <memory>
using namespace std;
class Foo{
public:
Foo(){
}
void printValue() {
cout << "This is Foo object " << endl;
}
};
int main(int argc, char *argv[])
{
Foo* f = new Foo();
std::shared_ptr<Foo> mySharedPtr(f);
f->printValue();
mySharedPtr.get()->printValue();
return 0;
}

Related

Extending/Incrementing the ref count of a smart pointer

Suppose I have a method that defines a shared_ptr. After the method finishes, the shared_ptr will also be deleted. In the interim I have another member that uses that shared_ptr. So I would like to extend the lifetime of the shared_ptr past the initial method.
void initial_method(int input)
{
std::shared_ptr<int> a { std::make_shared<int>(input) };
some_delayed_method(a);
}
Is it possible to manually increase the reference count of a by one in this example?
some_delayed_method() is like a detachment and is referring to a at a time after the initial_method() has returned.
Since you can't call some_delayed_method without a shared_ptr to the object and any shared_ptr to the object extends its lifetime, there is nothing you need to do.
If some_delayed_method saves the pointer in some external data structure, and this pointer will later be used, you should use shared_ptr for that.
class X
{
public:
void initial_method(int input)
{
std::shared_ptr<int> a { std::make_shared<int>(input) };
some_delayed_method(a);
}
void some_delayed_method(const std::shared_ptr<int>& a)
{
use_later = a;
}
private:
std::shared_ptr<int> use_later;
}
This way, the reference count will be handled automatically.
You may insist on using a raw pointer to save the data for later:
void some_delayed_method(const std::shared_ptr<int>& a)
{
use_later = a.get();
}
...
int* use_later;
This is not a proper way to save the data. To make it work (or appear to work), you have to do some hack. For example, make another reference to the data, and leak it:
void some_delayed_method(const std::shared_ptr<int>& a)
{
use_later = a.get();
new std::shared_ptr<int>(a); // horrible hack; please never do it! but it works...
}
This hack leaks the allocated std::shared_ptr so it can never be deleted, thus its refcount is not decremented and the allocated int is leaked.

Best way to protect from multiple shared_ptr to the same object

Sending the same pointer into two different shared_ptr's is bad, it causes double deallocation, like thus:
int* p = new int;
std::shared_ptr<int> p1(p);
std::shared_ptr<int> p2(p); // BAD
You can accomplish the same purpose with std::enable_shared_from_this:
class Good: public std::enable_shared_from_this<Good>
{
public:
std::shared_ptr<Good> getptr() {
return shared_from_this();
}
};
int main()
{
std::shared_ptr<Good> gp1(new Good);
std::shared_ptr<Good> gp2 = gp1->getptr();
}
But that still doesn't protect against:
class Good: public std::enable_shared_from_this<Good>
{
public:
std::shared_ptr<Good> getptr() {
return shared_from_this();
}
};
int main()
{
Good* p = new Good;
std::shared_ptr<Good> gp3(p);
std::shared_ptr<Good> gp4(p); // BAD
}
which could become a problem if you have code like this:
void Function(std::shared_ptr<Good> p)
{
std::cout << p.use_count() << '\n';
}
int main()
{
Good* p = new Good;
std::shared_ptr<Good> p1(p);
Function(p); // BAD
}
Why would I use a regular pointer when there's smart pointers? Because in performance critical code (or for convenience) the overhead of shared_ptr or weak_ptr is undesirable.
To prevent this mistake, I've done:
class CResource : public shared_ptr<Good>
{
public:
CResource()
{
}
CResource(std::shared_ptr<CBaseControl> c)
: CResource(c)
{
}
private:
CResource(CBaseControl* p)
{
}
};
void Function(CResource p)
{
std::cout << p.use_count() << '\n';
}
int main()
{
Good* p = new Good;
CResource p1(std::shared_ptr<Good>(p));
Function(p); // Error
}
This would cause the compiler to error if anyone tries to call Function with a pointer instead of a shared_ptr. It doesn't prevent someone from declaring void Function(std::shared_ptr p) though, but I think that's unlikely.
Is this still bad? Is there a better way of doing this?
The solution is simple: never have a raw pointer own memory in the first place. This pattern:
int* p = new int;
std::shared_ptr<int> p1(p);
std::shared_ptr<int> p2(p); // BAD
Simply shouldn’t exist. Eradicate it from your code base. The only places where new is legitimate in C++11 is as an argument to a constructor call to a smart pointer (or in very low level stuff).
I.e. have code like this:
std::shared_ptr<int> p1(new int);
Or better yet (no naked new involved any longer):
auto p1 = std::make_shared<int>();
Note that it’s fine to use raw pointers in code (but I’d question even that in most C++ code I’ve seen). But if you use raw pointers, don’t let them own the memory. Either point to automatic storage (no resource management necessary) or use a unique_ptr and access the raw pointer via its get member function.
This example doesn't even compile:
void Function(std::shared_ptr<Good> p)
{
std::cout << p.use_count() << '\n';
}
int main()
{
Good* p = new Good;
std::shared_ptr<Good> p1(p);
Function(p); // BAD
}
shared_ptr has an explicit constructor precisely to stop that happening.
To make that compile you need to write:
Function( std::shared_ptr<Good>(p) );
which is pretty obviously wrong, and if someone's going to make that mistake they're just as likely to do:
Function( CResource(std::shared_ptr<Good>(p)) );
So why have you bothered to write CResource? What does it add?
To expand on Konrad Rudolph's excellent answer:
The answer to your question of how to avoid problems is to follow the RAII idiom, but follow it fully.
We'll ignore the example that doesn't even compile and look at the one above it:
Good* p = new Good;
std::shared_ptr<Good> gp3(p);
std::shared_ptr<Good> gp4(p); // BAD
That code fails to follow the RAII idiom. You acquire a resource:
Good* p = new Good;
But do not initialize an RAII type. BAD.
Then you initialize an object with some existing resource:
std::shared_ptr<Good> gp3(p);
This is also BAD. You should initialize an RAII type at the same time as acquiring the resource, not separately (not even only separated by one line.)
Then you repeat the same error:
std::shared_ptr<Good> gp4(p); // BAD
You've marked this line as "BAD" but actually the previous two lines were just as bad. The third line will cause undefined behaviour, but the first two lines allowed that error to creep in, when it should have been made more difficult. If you never had a Good* hanging around then you couldn't have used it to initialize gp4, you'd have needed to say shared_ptr<Good> gp4(gp3.get()) which is so obviously wrong noone will do it.
The rule is pretty simple: Don't take a raw pointer and put it in a shared_ptr. A raw pointer you didn't allocate is not resource acquisition so don't use it for initialization. The same applies inside Function, it should not take the raw pointer and use it to initialize a shared_ptr that takes ownership of the type.
This is C++, so it's not possible to protect against all the wrong ways to write code, you can't prevent sufficiently motivated idiots from shooting themselves in the foot, but all the guidelines and tools are there to prevent it, if you follow the guidelines.
Whn you have an interface that forces you to transfer ownership by passing a raw pointer, try to replace the interface so it uses a unique_ptr for ownership transfer, or if it's totally impossible to do that then try to wrap the interface in a safer version using unique_ptr for ownership transfer, and only as a last resort, use the dangerous interface but document it very explicitly that ownership is transferred.

"delete this" to an object that's allocated with std::shared_ptr?

I know that it's possible to say delete this in C++ whenever you allocated something with new, using traditional pointers. In fact, I also know that it's good practice IF you handle it carefully. Can I have an object say delete this if it's being held by an std::shared_ptr? And that ought to call the destructor, right? To give you an idea, I'm making a game where a ship can shoot missiles, and I'd like to have the missiles delete themselves.
No, it's not safe, the lifetime of the object is determined by holders of shared_ptr, so the object itself cannot decide whether it wants to die or not. If you do that, you'll get double
delete when last shared_ptr dies. The only solution I can offer is "rethink your design" (you probably don't need shared_ptr in the first place, and missiles probably could be values or pooled objects).
For a missile to delete itself it must own itself, or at the very least, share ownership of itself with others. Since you say that there is a shared_ptr to the missile, I am assuming that you already have multiple objects sharing ownership of the missile.
It is possible for the missile to hold a shared_ptr to itself, and thus share in the ownership of itself. However this will always create a cyclic ownership pattern: For as long as the missile's shared_ptr data member refers to itself, the reference count can never drop to zero, and thus the missile is leaked.
You could have an external object or event tell the missile to delete itself but then I'm not sure what the point is. In order to tell the missile to delete itself, that communication should take place via a shared_ptr, and then the delete isn't really going to happen until that shared_ptr lets go of the missile.
Yes, it is possible. No, I don't think it is a good idea. It looks prone to memory leakage to me and doesn't actually add value. But for the curious, here is how you would do it:
#include <iostream>
#include <memory>
class missile
: public std::enable_shared_from_this<missile>
{
std::shared_ptr<missile> self_;
public:
missile()
{}
~missile() {std::cout << "~missile()\n";}
void set_yourself()
{
self_ = shared_from_this();
}
void delete_yourself()
{
if (self_)
self_.reset();
}
};
int main()
{
try
{
std::shared_ptr<missile> m = std::make_shared<missile>();
m->set_yourself();
std::weak_ptr<missile> wp = m;
std::cout << "before first reset()\n";
m.reset();
std::cout << "after first reset()\n";
// missile leaked here
m = wp.lock();
m->delete_yourself();
std::cout << "before second reset()\n";
m.reset(); // missile deleted here
std::cout << "after second reset()\n";
}
catch (const std::exception& e)
{
std::cout << e.what() << '\n';
}
}
I know I'm late to the show but I ran into wanting to do this myself just now and realized that it is "kind-of-possible" but you need to take care of a few things.
Howard's answer is on the right track but misses the mark as you shouldn't leave construction of the original shared_ptr to the client. This is what opens up the risk of memory leaks. Instead you should encapsulate the construction and only allow weak pointers.
Here is an example:
class Missile{
private:
Missile(...){ }; // No external construction allowed
Missile(const Missile&) = delete; // Copying not allowed
void operator = (const Missile&) = delete; // -||-
std::shared_ptr<Missile> m_self;
public:
template<typename... Args>
static MissilePtr makeMissile(Args... args){
auto that = std::make_shared<Misile>(args...);
that.m_self = that; // that holds a reference to itself (ref count = 2)
return that; // 'that' is destroyed and ref-count reaches 1.
}
void die(){
m_self.reset();
}
...
};
typedef std::weak_ptr<Missile> MissilePtr;
void useMissile(MissilePtr ptr){
auto missile = ptr.lock(); // Now ptr cannot be deleted until missile goes out of scope
missile->die(); // m_self looses the reference but 'missile' still holds a reference
missile->whatever(); // Completely valid. Will not invoke UB
} // Exiting the scope will make the data in missile be deleted.
Calling die() will result in semantically the same effect as delete this with the added benefit that all MissilePtr that are referring to the deleted object will be expired. Also if any of the MissilePtr are used for accessing this then the deletion will be delayed until the temporary std::shared_ptr used for the access is destroyed saving you life-time headaches.
However you must make sure that you always keep at least one MissilePtr around and at some point call die() otherwise you will end up with a memory leak. Just like you would with a normal pointer.
This question is quite old, but I had a similar issue (in this case a "listener" object that had to manage its own lifecycle while still being able to share weak pointers), and googling around did not provide a solution for me, so I am sharing the solution I found, assuming that:
The object manages it's own lifecycle, and hence will never share a
share_ptr, but a weak_ptr (if you need shared_ptr's a similar
solution + use_shared_from_this could do it).
It is a bad idea to break RAII, and hence we will not do it: what we
adress here is the issue of having a shared_ptr owned by an object
itself, as containing a member share_ptr leads to double call to
the object destruction and normally a crash (or at least undefined
behaviour), as the destructor is called twice (once at normal
object destruction and a second one when destroying the self
contained shared_ptr member).
Code:
#include <memory>
#include <stdio.h>
using std::shared_ptr;
using std::weak_ptr;
class A {
struct D {
bool deleted = false;
void operator()(A *p) {
printf("[deleter (%s)]\n", p, deleted ? "ignored":"deleted");
if(!deleted) delete p;
}
};
public: shared_ptr<A> $ptr = shared_ptr<A>(this, D());
public: ~A() {
std::get_deleter<A::D>($ptr)->deleted = true;
}
public: weak_ptr<A> ptr() { return $ptr; }
};
void test() {
A a;
printf("count: %d\n", a.ptr().lock().use_count());
printf("count: %d\n", a.ptr().use_count());
}
int main(int argc, char *argv[]) {
puts("+++ main");
test();
puts("--- main");
}
Output:
$ g++ -std=c++11 -o test test.cpp && ./test
+++ main
count: 2
count: 1
[deleter (ignored)]
--- main
The shared_ptr deleter should never get called for an object allocated in stack, so when it does at normal object destruction, it just bypasses the delete (we got to this point because the default object destructor was already called).

C++: How do I prevent a function from accepting a pointer that is allocated in-line?

Couldn't figure out how to word the question accurately, so here's an example:
Given this function prototype:
void Foo(myClass* bar);
I want to prevent this usage:
Foo(new myClass());
and instead require a previously created object:
myClass* bar = NULL;
bar = new myClass();
Foo(bar);
or
myClass bar;
Foo(&bar);
Thanks.
EDIT
Here's a clarified example:
void Mouse::SetImage(BITMAP* image, int focusX, int focusY) {
if(_image) {
set_mouse_sprite(NULL);
set_mouse_sprite_focus(0, 0);
show_mouse(NULL);
destroy_bitmap(_image);
_image = NULL;
}
if(image) {
_image = create_bitmap(image->w, image->h);
clear_bitmap(_image);
blit(image, _image, 0, 0, 0, 0, image->w, image->h);
}
if(image == NULL) {
focusX = 0;
focusY = 0;
}
_focusX = focusX;
_focusY = focusY;
_dirtyImage = true;
}
Whatever image the user passes in gets copied to the object's image.
If I deallocate the passed in image after copying it and the image is used elsewhere in the program it will crash the program with an access violation.
If they allocate the storage in-line and I don't deallocated it, a memory leak occurs. The problem is compounded if they call the SetImage method multiple times over the course of the running program.
Comments about using alternative libraries or on the Allegro Library itself will be ignored, I already know it's horrible. I don't have a choice.
Your design needs to make a choice. Either take ownership and delete it, or don't take ownership. Either way, it's up to the user to know how to use your function. They either need to know that your function will destroy the image (and maybe pass their own copy as needed), or they need to be smart enough to manage their own resources.
Typically, you don't want to steal ownership away just to delete it. So I would not delete anything. If someone is silly enough to lose the ability to delete the image they pass, that's not this functions problem. In other words, you should try to protect against Murphy, but forget about protecting against Machiavelli.
That said, raw pointer use is bad! Poor C++ code is marked by manual resource management and resource issues. You should have a wrapper around an image, that will delete the image in the destructor. That way you can never leak, even if an exception is thrown. Provide it with a reset() method which discards it's old image resource and gets a new one.
It sounds like you want shared ownership, so you'll want a reference counted resource wrapper. The issue is then solved: if someone does an "inline" allocation, it'll be put into the shared pointer and then deleted automatically when it's done. (And even better is to have an explicit constructor so someone has to know they'll be sharing the resource.)
This is done in a smart pointer called shared_ptr. Boost has one, TR1 has one, and C++0x has one. Just give it a custom deleted (one that frees the image), and you never worry about resource management again.
This should be done with all resources. The concept here is Scoped-bound Resource Management (SBRM); that a resource is managed automatically by taking advantage of the lifetime rules of automatic (stack) variables. It's known alos as it's original but uglier name Resource-Acquisition Is Initialization (RAII). Do some research into this area and you'll find your code is easier and cleaner.
It cannot be done without changing the type of the parameter. You could change it to:
void Foo(myClass*& bar);
Because a non-const reference can only be bound to an lvalue:
void foo(int*&);
int main(void)
{
int *i = 0;
int j;
foo(i); // well-formed
foo(&j); // ill-formed
foo(new int); // ill-formed
}
However, this disallows taking the address of an lvalue. You can of course do the simple:
int main(void)
{
int j;
int* pj = &j;
foo(pj); // well-formed
}
And it works. But I don't know why you'd want to do any of this.
The above solution would allow you to modify the argument (because it's a reference). If you wanted to enforce const within the function, you could make a utility like this:
template <typename T>
class require_lvalue
{
public:
require_lvalue(T& pX) :
mX(pX)
{}
const T& get(void) const
{
return mX;
}
operator const T&(void) const
{
return get();
}
private:
// non-copy-assignable
require_lvalue& operator=(const require_lvalue&);
const T& mX;
};
void foo(require_lvalue<int*>);
Same result, except you have a const-reference within the function.
Note that MSVC has a bug, and accepts this:
foo(new int);
in both cases, even though it shouldn't. (It does not accept new int(), however.)
It's impossible to have such a distinction of usage. And in all the cases it's a valid parameter. I really can't understand why you need this...
So don't use pointers... use (lvalue) references:
void Foo(myClass& bar);
Doesn't this solve your task?
But I anyway recommend something like std::auto_ptr for such cases.
#include <iostream>
void test(int *& ptr)
{
std::cout << *ptr << std::endl;
}
int main()
{
/* NEXT LINE WILL FAIL */
// test(new int(5));
int *b = new int(5);
test(b);
delete b;
return 0;
}
C or C++ does not give you the luxury of determining where the memory was allocated, that come into your function's parameters. If you want better safety then program in .NET.
If you want to make it safer, than just completely change your function signature to accept an auto pointer. that way the semantics become crystal clear, and there should be no confusion as to whom or what owns the memory.

How to retain local variable's value and revisit outside in C++

I use boost shared_ptr to wrap a pointer. However I can only get the correct value in test_shared_ptr(), while in main(), I get the wrong value.
Expected output:
100
100
Actual output:
100
-572662307
It seems that the pointer becomes invalid in that case. Any correct approach to do the job? Thanks in advance.
Below is the source code.
#include <memory>
#include <iostream>
class TestClass
{
public:
TestClass(int &i);
void print_i();
private:
int *_i;
};
TestClass::TestClass(int &i) : _i(&i)
{
}
void TestClass::print_i()
{
std::cout << *_i << std::endl;
}
void print_i(int &i)
{
std::cout << i << std::endl;
}
TestClass *test_shared_ptr()
{
std::tr1::shared_ptr<int> i(new int());
*i = 100;
print_i(*i);
return new TestClass(*i);
}
int main(int argc, char** argv)
{
TestClass *p = test_shared_ptr();
p->print_i();
return 0;
}
You need to pass around the shared pointer, rather than references and pointers directly to the int.
What's happening is the shared pointer is never passed anywhere outside the test_shared_ptr() function. When that function returns, the shared pointer is destroyed. When it sees that nothing else has a reference to it's memory, it destroys the memory it was pointing at.
Basically, where you are using int &i and int *i change both to use std::tr1::shared_ptr<int> i.
You probably need to read up on shared pointer a bit more. Basically, they keep a reference count for the pointer they are pointing to. When they are copied, they up the reference count, and when they are destroyed the decrement it. When the reference count reaches 0 (nothing else is referencing the memory it is pointing at) it frees that memory. So, even though something is using that pointer in your case, because it did not use a shared pointer there is no way for the shared pointer to know that the memory is still being used, so it frees it.
It seems that the pointer becomes invalid in that case
Of course it becomes invalid. shared_ptr gets deleted when you leave test_shared_ptr, and i does not exist after that.
Any correct approach to do the job?
1) simply copy value of i. (use int i instead of int* i in TestClass). int is small, you won't lose anything.
or
2) use std::tr1::shared_ptr<int> instead of int* in TestClass.
The issue you are having is with your API contract.
I don't want to use shared pointer to pass variable values in TestClass's constructor, since I don't want to force the api user to use smart pointer
Your TestClass contract is currently looking like you want the caller to maintain the int item so that it has a lifetime longer than TestClass.
Your test case doesn't follow this contract rule however.
Actually I want to pass object by reference instead of generic type in my application.
Passing by reference or by pointer does not have anything to do with 'generic' type.
Here is a possible fix for your code testing your API, the scope of your int is then longer then sufficiently long (untill the end of the app) to handle all usages within TestClass
TestClass *test_shared_ptr(int &i)
{
i = 100;
print_i(i);
return new TestClass(i);
}
int main(int argc, char** argv)
{
std::tr1::shared_ptr<int> i(new int());
TestClass *p = test_shared_ptr(*i);
p->print_i();
return 0;
}
What you are doing really breaks the point of shared_ptr. Basically when you pass it out of that function is it magically supposed to break and, thus, not free the pointed too memory?
No. It frees it. Are you expecting the shared_ptr to still exist outside of the function so that when "p" drops out of scope it manages to call teh shared_ptr destructor? This can't happen. p is a pointer not a shared_ptr class.
Either return a shared_ptr or return the new'd pointer and delete it yourself.