So as to explain about pointers and references in this question I wrote this code.
MyClass& MyClass::MyInstance()
{
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
return myLocalVariable ;
}
one of the comments, by a really impressive high reputation SO user, simply states:
*new is always wrong. ALWAYS.
It is the first time I'm told about this: Is it a famous coding standard we all should know about ? What are the reasons behind ?
I'm normally pragmatic, however this is too much even for me!
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
Seriously? Why not simply:
static MyClass myLocalVariable{/*parameters*/};
The most obvious reason is that if you don't keep a copy of the pointer which new returned, you're not likely to ever call delete on it.
On a more human level, it will make people reading your code think less of you, and that's never a good thing either.
I believe the stated user meant that allocating a static object using new is dangerous as the memory will most probably be leaked. Even more importantly your variable is not a pointer but a reference so the chance that you never free the memory returned by new is even greater(how often do you delete the address of a reference?).
THE problem is more than just useless allocations.
If nobody calls delete on it, it won't be deleted. Sure, the memory will be released when the program ends but its destructor doesn't get called.
Compare the output of using Get() and Get2() in the code below:
#include <iostream>
struct A
{
~A(){std::cout << "Deleted\n";}
};
A& Get()
{
static A & a = *new A;
return a;
}
A& Get2()
{
static A a;
return a;
}
int main()
{
//Case 1
Get();
//Case 2
Get2();
}
The output of this program is nothing when calling Get and Deleted when calling Get2.
In other words, resources with nontrivial destructors (commit-on-close file handle for example) will not be destroyed properly at program termination in case 1, but will in case 2.
The problem is that a raw new does not specify ownership. If I new up an object and return it, who owns it? Does the creating function/object own it, or does the calling function? If you return smart pointers (std::shared_ptr and std::unique_ptr) you are specifying ownership.
Not specifying ownership is one of the easiest ways to leak memory. I have the hardest time, even with professional programmers, getting people to understand ownership and work with it. This is mostly prevented by using good types (smart pointers) that specify ownership, just by existing.
type* function(); // Unspecified ownership.
// Must be well documented and all users must read
// and follow the documentation.
std::unique_ptr<type> function(); // Calling function owns returned pointer.
// Single ownership.
std::shared_ptr<type> function(); // Calling function owns returned pointer.
// Shared ownership. Can have multiple owners.
std::weak_ptr<type> function(); // Calling function references returned pointer.
// Must lock pointer to get owned object, if not deleted.
// Shared ownership. Can have multiple owners.
These different types of pointers express ownership just by existing unlike raw pointers.
As for new always being wrong. That is an overbroad generalization. std::shared_ptr is created using the global function std::make_shared. As of C++11 there is no std::make_unique, but that will be fixed in C++14. The only way to create a std::unique_ptr is to use new and immediately assign the pointer to a std::unique_ptr.
There are also places where you would want a raw pointer and to manually use new and delete, but they tend to be very low level and most programmers will rarely encounter them.
What really has me cringing about your code is not that you are using new but that you are dereferencing the pointer and assigning it to a reference. It would be almost impossible to guarantee that the destructor will ever be called. It also tends to leak memory, though in the case of assigning to a static variable it will be deallocated at program termination so you aren't really looking at memory leaking.
MyClass& MyClass::MyInstance()
{
static MyClass & myLocalVariable = * new MyClass(/*parameters*/);
return myLocalVariable ;
}
I would prefer to create to have the static variable be by value than by reference. This prevents putting the object on the heap. Depending on MyClass is could also allow the object to be mapped to memory from the executable without having to run any code to initialize it.
MyClass& MyClass::MyInstance()
{
static MyClass myLocalVariable(/*parameters*/);
return myLocalVariable ;
}
Related
always delete pointer even if it is just in function call stack?
Isn't it disappeared when function stack released?
// just Simple class
class CSimple{
int a;
}
// just simple function having pointer.
void simpleFunc(){
CSimple* cSimple = new CSimple();
cSimple->a = 10;
//.. do sth
delete cSimple; // <<< Always, do I have to delete 'cSimple' to prevent the leak of memory?
}
void main(){
for( int =0 ; i< 10 ; i++){
simpleFunc();
}
}
when function stack released?
It is true that "CSimple *csimple" goes away when the function returns.
However, there's a big difference between the pointer, and what it's pointed to.
When a pointer object gets destroyed, nothing happens to whatever the pointer is pointing to. There isn't just one, but two objects here:
The pointer.
What it's pointing to.
In this case, the pointer is pointing to an object in dynamic scope that was created with new.
Nothing is going to happen to this object, otherwise, so you will leak memory.
Therefore, this object needs to be deleted.
After you understand, and fully wrap your brain around this concept, your next step will be to open your C++ book to the chapter that talks about the std::unique_ptr and std::shared_ptr classes, which will take care of these pesky details, for you. You should learn how to use them. Modern C++ code rarely needs to delete something; rather these smart pointers do all the work.
Yes.
On scope exit (ex. when function exists or block { ... } finishes), all objects created on stack will be destroyed and memory will be freed.
This applies to your case, ie. the pointer will be destroyed and memory occupied by the pointer will be freed. The object pointed by the pointer will not be cleared.
This is a common problem and a nightmare when you deal with multiple flow paths (if-else ladders, many return statements) and exceptions.
To solve this problem, we employ 2 main strategies:
RAII
Smart pointers (std::unique_ptr, boost::scoped_ptr, legacy std::auto_ptr, etc).
RAII - without academic consideration - is just creating object on stack, like this:
{
std::string s;
fancy_object obj;
}
When we exit he scope, obj and s destructors will be called duing stack unwinding. Compiler ensures this for all flow paths and will keep proper order of deallocations for us.
If you need to allocate memory on heap, using new, use a smart pointer.
int foo()
{
std::unique_ptr<Object> o(new Object);
... some more code ...
if( something ) { return -1 }
... some more code ...
if( something_else ) { return -2 }
else { not yet }
return 0;
}
As you can see, we can leave the scope using 3 "exists". Normally, you'd need to clear your memory in all cases, which is prone to human errors.
Instead of clearing the object manually in all 3 palces, we rely on automatic destructor call for objects created on stack. Compiler will figure it out. When we leave the scope, std::unique_ptr destructor will be called, calling delete on Object.
Don't be affraid of smart poiners. They are not "slow", "bloat" or other nonsense. Smart poiners are designed to have no overhead on access, adding extra security.
Very similar technique is used for locks. Check out std::lock_guard class.
Yes, you must delete the data that is being pointed to.
The pointer itself is on the stack and does not need to be deleten.
You can, however, store cSimple on the stack, then you don't have to delete it:
void simpleFunc(){
CSimple cSimple; // no new
cSimple.a = 10; // "." instead of "->"
//.. do sth
// no deletion
}
My following question is on memory management. I have for example an int variable not allocated dynamically in a class, let's say invar1. And I'm passing the memory address of this int to another classes constructor. That class does this:
class ex1{
ex1(int* p_intvar1)
{
ptoint = p_intvar1;
}
int* ptoint;
};
Should I delete ptoint? Because it has the address of an undynamically allocated int, I thought I don't need to delete it.
And again I declare an object to a class with new operator:
objtoclass = new ex1();
And I pass this to another class:
class ex2{
ex2(ex1* p_obj)
{
obj = p_obj;
}
ex1* obj;
};
Should I delete obj when I'm already deleting objtoclass?
Thanks!
Because it has the address of an undynamically allocated int I thought I don't need to delete it.
Correct.
Should I delete obj when I'm already deleting objtoclass?
No.
Recall that you're not actually deleting pointers; you're using pointers to delete the thing they point to. As such, if you wrote both delete obj and delete objtoclass, because both pointers point to the same object, you'd be deleting that object twice.
I would caution you that this is a very easy mistake to make with your ex2 class, in which the ownership semantics of that pointed-to object are not entirely clear. You might consider using a smart pointer implementation to remove risk.
just an appendix to the other answers
You can get rid of raw pointers and forget about memory management with the help of smart pointers (shared_ptr, unique_ptr).
The smart pointer is responsible for releasing the memory when it goes out of scope.
Here is an example:
#include <iostream>
#include <memory>
class ex1{
public:
ex1(std::shared_ptr<int> p_intvar1)
{
ptoint = p_intvar1;
std::cout << __func__ << std::endl;
}
~ex1()
{
std::cout << __func__ << std::endl;
}
private:
std::shared_ptr<int> ptoint;
};
int main()
{
std::shared_ptr<int> pi(new int(42));
std::shared_ptr<ex1> objtoclass(new ex1(pi));
/*
* when the main function returns, these smart pointers will go
* go out of scope and delete the dynamically allocated memory
*/
return 0;
}
Output:
ex1
~ex1
Should I delete obj when I'm already deleting objtoclass?
Well you could but mind that deleting the same object twice is undefined behaviour and should be avoided. This can happen for example if you have two pointers for example pointing at same object, and you delete the original object using one pointer - then you should not delete that memory using another pointer also. In your situation you might as well end up with two pointers pointing to the same object.
In general, to build a class which manages memory internally (like you do seemingly), isn't trivial and you have to account for things like rule of three, etc.
Regarding that one should delete dynamically allocated memory you are right. You should not delete memory if it was not allocated dynamically.
PS. In order to avoid complications like above you can use smart pointers.
You don't currently delete this int, or show where it's allocated. If neither object is supposed to own its parameter, I'd write
struct ex1 {
ex1(int &i_) : i(i_) {}
int &i; // reference implies no ownership
};
struct ex2 {
ex2(ex1 &e_) : e(e_) {}
ex1 &e; // reference implies no ownership
};
int i = 42;
ex1 a(i);
ex2 b(a);
If either argument is supposed to be owned by the new object, pass it as a unique_ptr. If either argument is supposed to be shared, use shared_ptr. I'd generally prefer any of these (reference or smart pointer) to raw pointers, because they give more information about your intentions.
In general, to make these decisions,
Should I delete ptoint?
is the wrong question. First consider things at a slightly higher level:
what does this int represent in your program?
who, if anyone, owns it?
how long is it supposed to live, compared to these classes that use it?
and then see how the answer falls out naturally for these examples:
this int is an I/O mapped control register.
In this case it wasn't created with new (it exists outside your whole program), and therefore you certainly shouldn't delete it. It should probably also be marked volatile, but that doesn't affect lifetime.
Maybe something outside your class mapped the address and should also unmap it, which is loosely analogous to (de)allocating it, or maybe it's simply a well-known address.
this int is a global logging level.
In this case it presumably has either static lifetime, in which case no-one owns it, it was not explicitly allocated and therefore should not be explicitly de-allocated
or, it's owned by a logger object/singleton/mock/whatever, and that object is responsible for deallocating it if necessary
this int is being explicitly given to your object to own
In this case, it's good practice to make that obvious, eg.
ex1::ex1(std::unique_ptr<int> &&p) : m_p(std::move(p)) {}
Note that making your local data member a unique_ptr or similar, also takes care of the lifetime automatically with no effort on your part.
this int is being given to your object to use, but other objects may also be using it, and it isn't obvious which order they will finish in.
Use a shared_ptr<int> instead of unique_ptr to describe this relationship. Again, the smart pointer will manage the lifetime for you.
In general, if you can encode the ownership and lifetime information in the type, you don't need to remember where to manually allocate and deallocate things. This is much clearer and safer.
If you can't encode that information in the type, you can at least be clear about your intentions: the fact that you ask about deallocation without mentioning lifetime or ownership, suggests you're working at the wrong level of abstraction.
Because it has the address of an undynamically allocated int, I
thought I don't need to delete it.
That is correct. Simply do not delete it.
The second part of your question was about dynamically allocated memory. Here you have to think a little more and make some decisions.
Lets say that your class called ex1 receives a raw pointer in its constructor for a memory that was dynamically allocated outside the class.
You, as the designer of the class, have to decide if this constructor "takes the ownership" of this pointer or not. If it does, then ex1 is responsible for deleting its memory and you should do it probably on the class destructor:
class ex1 {
public:
/**
* Warning: This constructor takes the ownership of p_intvar1,
* which means you must not delete it somewhere else.
*/
ex1(int* p_intvar1)
{
ptoint = p_intvar1;
}
~ex1()
{
delete ptoint;
}
int* ptoint;
};
However, this is generally a bad design decision. You have to root for the user of this class read the commentary on the constructor and remember to not delete the memory allocated somewhere outside class ex1.
A method (or a constructor) that receives a pointer and takes its ownership is called "sink".
Someone would use this class like:
int* myInteger = new int(1);
ex1 obj(myInteger); // sink: obj takes the ownership of myInteger
// never delete myInteger outside ex1
Another approach is to say your class ex1 does not take the ownership, and whoever allocates memory for that pointer is the responsible for deleting it. Class ex1 must not delete anything on its destructor, and it should be used like this:
int* myInteger = new int(1);
ex1 obj(myInteger);
// use obj here
delete myInteger; // remeber to delete myInteger
Again, the user of your class must read some documentation in order to know that he is the responsible for deleting the stuff.
You have to choose between these two design decisions if you do not use modern C++.
In modern C++ (C++ 11 and 14) you can make things explicit in the code (i.e., do not have to rely only on code documentation).
First, in modern C++ you avoid using raw pointers. You have to choose between two kinds of "smart pointers": unique_ptr or shared_ptr. The difference between them is about ownership.
As their names say, an unique pointer is owned by only one guy, while a shared pointer can be owned by one or more (the ownership is shared).
An unique pointer (std::unique_ptr) cannot be copied, only "moved" from one place to another. If a class has an unique pointer as attribute, it is explicit that this class has the ownership of that pointer. If a method receives an unique pointer as copy, it is explicit that it is a "sink" method (takes the ownership of the pointer).
Your class ex1 could be written like this:
class ex1 {
public:
ex1(std::unique_ptr<int> p_intvar1)
{
ptoint = std::move(p_intvar1);
}
std::unique_ptr<int> ptoint;
};
The user of this class should use it like:
auto myInteger = std::make_unique<int>(1);
ex1 obj(std::move(myInteger)); // sink
// here, myInteger is nullptr (it was moved to ex1 constructor)
If you forget to do "std::move" in the code above, the compiler will generate an error telling you that unique_ptr is not copyable.
Also note that you never have to delete memory explicitly. Smart pointers handle that for you.
I never used any kind of smart pointer, but I keep reading about them almost everywhere when the topic is pointers. I do understand that there are situations where smart pointers are much nicer to work with than raw pointers, because to some extend they manage ownership of the pointer. However, I still do not know, where is the line between "I do not needing smart pointers for that" and "this is a case for smart pointers".
Lets say, I have the following situation:
class A {
public:
double get1(){return 1;}
double get2(){return 2;}
};
class SomeUtilityClass {
public:
SomeUtilityClass(A* a) : a(a) {}
double getResult(){return a->get1() + a->get2();}
void setA(A* a){a = a;}
private:
A* a;
};
int main(int argc, char** argv) {
A a;
SomeUtilityClass u(&a);
std::cout << u.getResult() << std::endl;
A a2;
u.setA(&a2);
std::cout << u.getResult() << std::endl;
return 0;
}
This is of course an oversimplified example. What I mean is that SomeUtilityClass is not supposed to "own" an instance of A (because it is just a utility class), thus it just holds a pointer.
Concerning the pointer, the only thing that I am aware of that could go wrong is:
SomeUtilityClass can be instantiated with a null pointer
The object pointed to may be deleted/go out of scope, without the SomeUtilityClass noticing it
How could a smart pointer help to avoid this problem? What other benefits I would get by using a smart pointer in this case?
PS: I know that there are several question on smart pointers (e.g. this one). However, I would appreciate, if you could tell me about the impact on this particular example.
This depends on how the parameter is created and stored. If you don't own the memory and it could be either statically or dynamically allocated, a raw pointer is a perfectly reasonable solution -- especially if you need to support swapping of the data as in your example. Another option would be to use std::reference_wrapper, which would get rid of your nullptr issue whilst keeping the same semantics.
If you are holding a pointer to some shared resource (i.e. stored in a std::shared_ptr somewhere) and want to be able to check if it has been deleted or not, you could hold a std::weak_ptr.
For the purposes of this answer I'm redefining setA as:
void setA(A* new_a){a = new_a;}
Consider:
// Using your SomeUtilityClass
int main() {
A a;
SomeUtilityClass u(&a);
// We define a new scope, just because:
{
A b;
u.setA(&b);
}
std::cout << u.getResult() << '\n';
return 0;
}
After the scope is finished, SomeUtilityClass has a dangling pointer and getResult() invokes Undefined Behaviour. Note that this can't be solved with a reference: You would still get a dangling one.
Now consider the version using a smart pointer:
class SomeUtilityClass {
public:
SomeUtilityClass(std::shared_ptr<A>& a) : a{a} {}
double getResult(){return a->get1() + a->get2();}
void setA(std::shared_ptr<A>& new_a){a = new_a;}
private:
std::shared_ptr<A> a;
};
int main() {
std::shared_ptr<A> a{new A};
SomeUtilityClass u{a};
// We define a new scope, just because:
{
std::shared_ptr<A> b{new A};
u.setA(b);
}
std::cout << u.getResult() << '\n';
return 0;
}
Because you have shared ownership, there's no way to get a dangling pointer. The memory pointed to by b will be deleted as usual, but only after u is destroyed(or its pointer is changed).
IMHO, in most cases you should be using smart pointers (Even when at first it doesn't seem to make much sense). It makes maintenance much easier. Use raw pointers only in specific code that actually needs them, and encapsulate/isolate this code as much as possible.
If SomeUtilityClass does not own the member variable a, then a smart pointer does not make sense.
You might consider a reference member, which would remove the problems of a null pointer.
The default way of expressing not-owning pointer in C++ is weak_ptr. To use weak_ptr you need to use shared_ptr for ownership, so in your example you would use
shared_ptr<A> owner(...)
instead of
A a
Then as the private pointer member of your SomeUtilityClass you use weak pointer:
weak_ptr<A> w;
and initialise it with shared_ptr:
SomeUtilityClass(shared_ptr<A> o) : w(o) {}
however, you cannot use weak_ptr directly, since the shared_ptr could go out of scope and your weak pointer can no longer point to anything. Before use you need to lock it:
shared_ptr<A> locked = w.lock();
The locked pointer will be empty if the owning pointer no longer manages an object, since e.g. it went out of scope. If it is not empty, you may use it and then it will go out of scope automatically releasing the lock the object.
Both shared_ptr and weak_ptr are available in standard library in C++11, and in Boost for older compilers.
There are different types of smart pointers. In your case, it is clear that a smart pointer is not really needed, but it may still provide some benefits.
SomeUtilityClass can be instantiated with a null pointer
This one is probably best solved with a check in the constructor, throwing an exception or indicating an error in some other way in the case when you get a NULL pointer as the argument. I can hardly imagine how a smart pointer would help, unless you use a specific smart pointer class that doesn't accept NULLs, so it does the check for you already.
The object pointed to may be deleted/go out of scope, without the
SomeUtilityClass noticing it
This one can actually be resolved with a special type of smart pointers, but then it is needed that the object being pointed to somehow supports notification of destruction. One such example is the QPointer class in the Qt library, which can only point to QObject instances, which notify it when deleted, so the smart pointer automatically becomes NULL when the object is deleted. There are some problems with this approach, though:
You need to check for NULLs every time you access the object through the smart pointer.
If a smart pointer points to an instance of a class, say MyClass, extending the class performing the deletion notification (QObject in the Qt case), you get strange results: it's the destructor of QObject that notifies the smart pointer, so it is possible that you access it when the MyClass destructor already began its dirty work, so the object is partially destructed, but the pointer is not NULL yet because the destruction is still in progress.
I know the title of the question looks a bit mind-damaging, but I really don't know how to ask this in one phrase. I'll just show you what I mean:
void f(T *obj)
{
// bla bla
}
void main()
{
f(new T());
}
As far as I know, (almost) every new requires a delete, which requires a pointer (returned by new). In this case, the pointer returned by new isn't stored anywhere. So would this be a memory leak?
Does C++ work some kind of magic (invisible to the programmer) that deletes the object after the function ends or is this practice simply always a bad idea?
There is no particular magic and delete will not be called automatically.
It is definitely not "always a bad idea" - if function takes ownership of an object in some form it is perfectly valid way for calling such function:
container.AddAndTakeOwnership(new MyItem(42));
Yes, it's always a bad idea; functions and constructors should be explicit about their ownership semantics and if they expect to take or share ownership of a passed pointer they should receive std::unique_ptr or std::shared_ptr respectively.
There are lots of legacy APIs which take raw pointers with ownership semantics, even in the standard library (e.g. the locale constructor taking a Facet * with ownership), but any new code should avoid this.
Even when constructing a unique_ptr or shared_ptr you can avoid using the new keyword, in the latter case using make_shared and in the former case writing a make_unique function template which should fairly soon be added to the language.
In this case, the pointer returned by new isn't stored anywhere. So
would this be a memory leak?
No, it is not necessarily a memory leak. The pointer is stored as an argument to f:
void f(T *obj)
// ^^^ here pointer is "stored"
{
// bla bla
delete obj; // no memory leak if delete will be called on obj
}
void main()
{
f(new T());
// ^^^^^^^ this "value" will be stored as an argument to f
}
Does C++ work some kind of magic (invisible to the programmer) that
deletes the object after the function ends or is this practice simply
always a bad idea?
No magic in your example. As I showed - delete must be called explicitly.
Better is to use smart pointer, then C++ "magic" works, and delete is not needed.
void f(std::unique_ptr<T> obj)
{
// bla bla
}
void main()
{
f(new T());
}
The code shown will result in a memory leak. C++ does not have garbage collection unless you explicitly use a specialized framework to provide it.
The reason for this has to do with the way memory is managed in C/C++. For a local variable, like your example, memory for the object is requested directly from the operating system (malloc) and then the pointer to the object exists on the stack. Because C/C++ can do arbitrarily complex pointer arithmetic, the compiler has no way of knowing whether there exists some other pointer somewhere to the object, so it cannot reclaim the memory when function f() ends.
In order to prevent the leak automatically, the memory would have to be allocated out of a managed heap, and every reference into this heap would have to be carefully tracked to determine when a given object no longer was being used. You would have to give up C's ability to do pointer arithmatic in order to get this capability.
For example, let's say the compiler could magically figure out that all normal references to obj were defunct and deleted the object (released the memory). What if you had some insanely complicated RUNTIME DEPENDENT expression like void* ptr = (&&&&(&&&*obj)/2++ - currenttime() - 567 + 3^2 % 52) etc; How would the compiler know whether this ptr pointed to obj or not? There is no way to know. This is why there is no garbage collection. You can either have garbage collection OR complex runtime pointer arithmetic, not both.
This is often used when your function f() is storing the object somewhere, like an array (or any other data container) or a simple class member; in which case, deletion will (and must) take place somewhere else.
Otherwise is not a good idea cause you will have to delete it manually at the end of the function anyway. In that case, you can just declare an automatic (on the stack) object and pass it by pointer.
No magic. In your case after f is called main returns back to CRT's main and eventually the OS will clean up the "leak". Its not necessarily a bad idea, it could be giving f the ownership and it is up to f to do stuff and eventually delete. Some make call it bad practice but its probably out there in the wild.
Edit:
Although I see that code no more dangerous than:
void f(T *obj)
{
// bla bla
}
void main()
{
T* test = new T ();
f(test);
}
Principally it is the same. Its saying to f, here is a pointer to some memory, its yours you look after it now.
In C++ passing a pointer is discouraged as there are no associated owner semantics (ie you can not know who owns the pointer and thus who is responsible for deleting the pointer). Thus when you do have a function (that takes a pointer) you need to document very clearly if the function is responsible for cleaning up the pointer or not. Of course documentation like this is very error prone as the user has to read it.
It is more normal in C++ program to pass objects that describe the ownership semantics of the thing.
Pass by reference
The function is not taking ownership of the object. It will just use the object.
Pass a std::auto_ptr (or std::unique_ptr)
The function is being passed the pointer and ownership of the pointer.
Pass a std::shared_ptr
The function is being passed shared ownership of the pointer.
By using these techniques you not only document the ownership semantics but the objects used will also automatically control the lifespan of the object (thus relieving your function from calling delete).
As a result it is actually very rare to see a manual call to delete in modern C++ code.
So I would have written it like this:
void f(std::unique_ptr<T> obj)
{
// bla bla
}
int main()
{
f(std::unique_ptr<T>(new T()));
}
I am not experienced in handling of the memory in a C++ program, so I would like a piece of advice in that case:
I want to create a new Object in a function in a class which is essential till the end of the program. As far as I am concerned, if I use the operator new, I should sometimes delete it. Taking into account that it must be initialized inside a class, when and how must I finally delete it?
I suggest the smart pointer idiom
#include <memory>
struct X
{
void foo() { }
};
std::share_ptr<X> makeX() // could also be a class member of course
{
return std::make_shared<X>();
}
int main()
{
std::share_ptr<X> stayaround = makeX();
// can just be used like an ordinary pointer:
stayaround->foo();
// auto-deletes <sup>1</sup>
}
If the pointer is truly a static variable, you can substitute a unique_ptr (which works similarly, but passes ownership on assignment; this means that the pointer doesn't have to keep a reference count)
Note To learn more about C++ smart pointers in general, see smart pointers (boost) explained
Note If you don't have the TR1/C++0x support for this, you can just use Boost Smartpointer
1 unless you are leaking copies of the shared_ptr itself; that would be some strange use of smart pointers previously unseen :)
Edit: Using some sort of smart pointer is often a good idea, but I believe it is still essential to have a solid understanding of manual memory management in C++.
If you want an object in a class to persist until the end of the program, you can simply make it a member variable. From what you've said, there's nothing to suggest you need to use new or delete here, just make it an automatic variable. If you did want to use new and delete for practice, you should read up on constructors and destructors for a class (you can and will use new and delete outside of classes, but I'm trying to keep this relevant to your question). Here's one I prepared earlier:
class Foo
{
public:
Foo(); // Default constructor.
~Foo(); // Destructor.
private:
int *member;
}
Foo::Foo() // Default constructor definition.
{
member = new int; // Creating a new int on the heap.
}
Foo::~Foo() // Destructor.
{
delete member; // Free up the memory that was allocated in the constructor.
}
This is a simple example, but it will hopefully help you out. Note that the variable will only persist as long as the object is alive. If the object is destroyed or goes out of scope, the destructor will be called and the memory will be freed.
You can use the smart pointer as suggested by Sehe or you can create a static object in the function and return a reference to it. You need not explictly delete the object, when the process terminates the object will be deleted. Like:
struct X {};
X& makeX() // could also be a class member of course
{
static X x;
return x;
}
int main()
{
X& stayaround = makeX();
}
On most operating systems (in particular Linux), if you allocate an object pointer with new Object, and don't bother delete-ing because you'll need it till the program ends, no harm is really done. There is some memory leak inside your program (you can use valgrind to hunt such leaks) but the kernel will release all the memory used by a process when it has ended.
A better alternative is to have a singleton class for the application data, like e.g. QApplication in Qt, ahd construct a single instance in that class early in your main, and have that class contain a smart or dumb pointer to your Object. The destructor should delete that object.