I'd like to illustrate one thing I've seen:
class Something {};
void do_something(const Something *p_sth) {}
Then:
do_something(new Something());
should cause a memory leak because when you call new you should also always call delete, right? Would this be a good solution?
void do_something(const Something *p_sth)
{
delete p_sth;
}
Or is it better to use references &? I also find out that smart pointers can solve this, so delete isn't required (it seems as a good thing but I have never used it before). I just want to know what's the best solution for this to avoid the memory leak. Thanks
*Thank you all for your answers. It helped me to clear up few things. I'm also sorry for the code I posted as it was maybe too general.
Your suggestion of assuming the ownership of the pointer and deleting the object has problems.
That behaviour is not idiomatic in c++. Programmers expect that they must delete every object that they allocate with new. If a user of your function expects that they're responsible for deleting the object whose address they pass to the function, then your solution breaks apart. Also, it prevents using your function with objects that must keep existing after the call has ended:
Something* s = new s();
do_something(s);
s.foo() // oops, object was deleted, I can't use it anymore
delete s; // oops, double delete because I'm for some reason not responsible for deleting the object that I allocated
Your solution also prevents using automatically and statically allocated objects with the function.
Something s;
do_something(&s); //oops, do_something assumes that object is dynamically allocated
All of these caveats would have to be documented to the user of the function.
A raw pointer without deleting inside the function has none of these problems. Managing the callers memory should really not be the responsibility of your function. Doing that would break the single responsibility principle. There's nothing wrong with raw pointer parameters when you don't want to transfer or share ownership. If you do want to imply changes in ownership, then use smart pointers which were designed exactly for that.
Smart pointers don't have some of the above problems, but they still prevent using the function with automatic and static objects.
A reference parameter is in many cases ideal. It communicates the caller that they're still responsible for the object. As a bonus, The lack of need for addressof operator allows slightly nicer syntax. Sure, the caller may still forget to manage their memory, but as I pointed out, that shouldn't be your responsibility.
References have one potential drawback. They can't be null. If you don't need null, then it's actually an advantage.
Which solution is ideal, depends on what you need. Following is not true for all corner cases, but should hold for most common cases:
If you want to modify the object, then pass a reference.
Unless you need null, in which case use a pointer
If you just want to read the object, then
If the object is copyable, small (size less than or equal to word), doesn't cointain pointers to dynamic objects and not polymorphic, then pass by value
Otherwise or if you don't know those things because you're writing a template, pass a const reference
Unless you need null, in which case use a pointer
If you want to If you want to transfer ownership, then use unique_ptr
If you want that ownership to be shared, then use shared_ptr
Best is to use a smart pointer
class Something {};
void do_something(std::shared_ptr<Something> p_sth)
{
...
}
That way the ownership is clear when you look at the prototype as well as you get an automatic delete when you leave scope.
I just want to know what's the best solution for this to avoid the memory leak. Thanks
The best solution to ensure there are no memory leaks would be to use std::shared_ptrwhich is a smart pointer which, as soon as it does not have any references, deletes itself. This pointer is best if you have more than on reference to the same pointer. Use std::unique_ptr if there is only one reference at a given time.
This will prevent memory leaks and I also prefer using smart pointers rather than standard pointers as they are very powerful. Also, retaining to the question:
Or is it better to use references &?
Use references wherever you need to reference the object, if you delete the reference, being a smart pointer, it will delete the pointer as well (Being there are no other references to that pointer)
I hope this answers your questions :)
Prefer to avoid the use of raw pointers.
If you do not need a heap allocation and can use a stack allocated variable, then prefer to pass by reference (or even pass by value if an appropriate move constructor is in place, but that's a topic for another day).
If you need a heap allocation (for polymorphism, dependency injection, information hiding, transfer of ownership etc.) then determine what the ownership semantics will be for that object and use the appropriate smart pointer to manage those semantics.
If all else fails and you must use a raw pointer (perhaps you are dealing with a legacy interface or a C interface, or something similar) then again, clearly define your ownership semantics and document them to make it clear who is responsible for deleting the heap allocated object, etc.
If you must have a raw pointer to a stack allocated object then document that you will not be deleting the pointer and be careful about documenting the lifetime of the pointer to avoid accessing the object after it has gone out of scope.
Cleanest solution would be to avoid the pointer completely.
And yes, a reference is a good idea.
void do_something(const Something &p_sth) {}
Then you can declare your 'something' on the Stack.
void function_that_does_something()
{
Something mySomething;
do_something( mySomething );
}
It is always best to let the compiler do the cleanup for you.
Related
I have a method which creates an object in an auto_ptr, sticks that auto_ptr into a vector, and then returns a raw pointer to the object for convenience.
The problem with this design is that it returns a raw pointer. It's really easy for the caller to misunderstand that this pointer is non-owned and wrap the result of this call into a managed pointer, which causes a memory access violation when that memory gets double free'd.
int main (void)
{
{
std::auto_ptr<int> foo = ThisMethodReturnsNonOwningPtr(); // Uhoh
}
ThisMethodUsesThePtr(); // Crash
return 0;
}
Ideally, I would like to return something like a pointer which can not be converted to a managed pointer so I don't have to worry about the caller doing this.
Alternatively, I might just return an index into the array, but it's real convenient just being able to pass the pointer around, and who knows maybe I will end up shuffling or sorting the array later.
First, if you can stick an auto_ptr into a vector, it's time to
upgrade your compiler or your library. This hasn't been legal
since the first standard in 1998. If you've got C++11, you can
use std::unique_ptr; if not, you'll need to keep raw pointers
in the vector. In both cases, you'll want to wrap the vector:
with std::unique_ptr, so that the client doesn't have to do
anything fancy to get the actual pointer, and with raw pointers,
so that you can manage the memory associated with them.
For the rest, just return a raw pointer. If you have
programmers that go around deleting random pointers, you're sunk
anyway; most of the time, raw pointers are for navigation, and
are just as likely to point to an object with static lifetime as
to anything else.
Stop using auto_ptr and start using unique_ptr or shared_ptr. The latter has reference counting so you can safely return the object and others can use it. The data it points to will not be freed until all references are released.
there is no other alternative if you need to safely return a pointer to the object and still be able to alter the vector. You could use a unique_ptr to prevent a caller from treating the returned pointer as if it owned it.
Last resort is to slap comments on the code to say that the vector owns the object and the pointer is only to be used as a convenience. Its not as good as getting the compiler to check calling code, but it can be the only way if you restrict your options as you mentioned.
Create a wrapper class template raw_ptr<T> which encapsulates a T*.
If you now implement operator* and operator-> but no conversion operator, you can no longer assign this pointer to another smart pointer, because that assignment would require two custom conversions (raw_ptr<T> → T* → smart_ptr<T>), which is not allowed in C++.
Notice that, as others have said, you should not use auto_ptr<T> – it’s deprecated for good reasons. Use std::unique_ptr<T> instead. For one thing, you cannot actually safely stick auto_ptrs into a std::vector, great care has to be taken to not accidentally copy (and thus invalidate) such pointers.
I'm always reluctant to write answers that depend on boost since not everyone is able to use it and it's almost always overkill to pull it in for just one little thing, but if you have it anyway, you could return a boost::optional<&>. On the surface it doesn't seem an optional reference could work, but it (mostly) does. See boost's documentation.
This would give you the nullability you require (return boost::none to indicate an error) while making it very clear that the caller is not to take ownership of the object.
If you don't want the object to be deleted in conventional means using delete operator, you could make the destructor of the class private and implement destroy() function which self-destructs the object.
Better would be if you could make the function return something like shared_ptr.
A third option could be just to have a class something like template<typename> struct non_ownership_ptr; which the function returns instead of a raw pointer. This pointer class just holds the pointer and you would have to explicitly use auto_ptr<T> p=foo().non_owned_ptr; to avoid (or at least reduce) accidental assignment to auto_ptr or such.
Is it okay( and legal) to delete a pointer that has been passed as a function argument such as this:
#include<iostream>
class test_class{
public:
test_class():h(9){}
int h;
~test_class(){std::cout<<"deleted";}
};
void delete_test(test_class* pointer_2){
delete pointer_2;
}
int main(){
test_class* pointer_1;
while(true){
pointer_1 = new test_class;
//std::cout<<pointer_1->h;
delete_test(pointer_1);
}
}
This compiles fine now, but I just want to make sure it'll always be that way.
It will always compile without error.
Whether it's a good thing to pass a pointer into a function and delete it in that function is potentially another story, depending on the specifics of your program.
The main idea you need to consider is that of "ownership" of the pointed-to data. When you pass that pointer, does the calling function have ownership of the data being passed in? i.e. is it in the only place that this data can be referenced from? Are you giving up ownership of the pointed-to-data, with no chance that the calling function is ever going to reference the data again? If so, then you must delete it.
If the calling function might reference the data again, then you must not delete it.
If there are other references to the data through various data structures, then it's not safe to delete this data unless you have some discipline in place in your code to ensure that you will never reference the data again from those places. This is hard to do, and is the source of many programming bugs.
C++ tr1's shared_ptr<> is a smart pointer that helps in these kinds of situations - it manages this ownership concept by keeping a reference count that tracks the number of references to the data. If the reference count is 1, then there is 1 clear owner. If the reference count is larger than 1, then ownership is shared. If the reference count is 0, then there are no more references to the data, and shared_ptr<> will delete it when the shared_ptr<> destructor is called.
Yes, this is valid.
This is commonly done in C (with malloc and free instead of new and delete, obviously). In C++, it is generally preferable to use other memory management idioms like RAII, if you can.
Yes it is legal in C++, but doing this is not generally considered as a good practice. It is always better for the class which performed new to delete the same.
Yes, this is perfectly legal. You can delete a pointer from wherever, as long as it points to some object allocated on the heap (or is equal to 0).
Whether the caller expects their object to be deleted by the function, that's another question.
That's completely legal, though in such a case it's probably better to manage memory ownership with something like boost::shared_ptr.
It is perfectly legal to do that. You must make sure that the pointer isn't used in the caller after that point. In general, the name of the function doing the delete should indicate that is what is happening (e.g., contain delete, release, free, etc). Another potential problem is making sure that the data pointed to was allocated with new and not new[].
It is valid and can be very useful when writing a cleanup method for the object, although 9/10 times you'd want to put the cleanup logic into the destructor.
One good reason though to write a separate cleanup would be if you want to keep the object "alive" but not used for awhile, maybe in an array or pool of objects that you pull from occasionally when you need a new one without wanting the constructor overhead.
If you are going to have pointers passed in you should check to make sure they aren't null to avoid any undefined behaviour.
Probably a bit late to the discussion, but I wanted to add a clarification: the function only takes a copy of the pointer ( fnc(int* a) is a pass by value) thus you're deleting the local copy of the pointer you've passed and the original pointer will remain available.
That code probably was optimized by the compiler to avoid unnecessary allocation and deletion which allowed it to work.
I have a method that has a few pointers as parameters. This method can be called with either named pointers from the callee or dynamically create a pointer to a new object and pass it in as an argument directly as the method is being called.
myClass *myPtr = new myClass(...);
myMethod(myPtr);
Verus
myMethod(new myClass(...));
The problem is that if both of these are valid options, how does one properly free the passed in pointer? Deleting myPtr within myMethod will cause a crash if myPtr is ever accessed again within the program. If I don't delete myPtr, the second option will cause a memory leak if it is used. There are benefits for using both options so both shouldn't break the program.
Aside from using STL, what are some solutions to this problem? Would I have to implement my own garbage collector?
I would say, in this case caller should be responsible for freeing the object. You can consider various options, simplest is:
myClass myInstance = myClass; // or myClass(arg1, arg2, ...)
// and the pass it to your method like this:
myMethod(&myInstance);
You could also consider some smart pointer options like std::tr1::shared_ptr or something from boost.
UPDATE: If your method should be able to get NULL-pointer as its argument, there's no problem at all:
// this is your method declaration:
void myMethod(const myClass *myPtr);
// in your tests or wherever in your code you can call it like
myClass myInstance = myClass; // or myClass(arg1, arg2, ...)
myMethod(&myInstance);
// or like this:
myMethod(NULL);
// for as long as your method has something like this in it:
if (myPtr)
myPtr->someMethod();
You can use a smart pointer for that, like shared_ptr from boost.
If not you need to state clearly who owns the object. If you are going to take over the ownership or leave it to the caller.
If you leave it to the caller, using the form function(new whatever()) wouldn't be a good idea, but the leak would be responsibility of the caller.
If you intent to take over the ownership, creating a sink method, choosing a proper name would be a good idea, of course you'd need to delete the objects by yourself once you are finished.
First thing, you need to assign ownership of the object: you need to have a consistent strategy (and enforced!) as to "who" has the right to delete an object. Once this is clearly established, you shouldn't have the problem you are running into.
Some strategies:
Object is leased: ownership is retained by lender
Object is given: ownership is transferred
Second, for tracking usage of an object, you need an infrastructure such as "smart pointers". Here you have 2 categories to care about:
Object is "singly referenced" i.e. only one "user"
Object is "multi referenced" i.e. more than one "user" at one point in time
For (1), the "tracking information" is the pointer itself whereas in (2) you need more infrastructure.
You should use some sort of smart pointer.
For this simple case ever auto_ptr is fine but in general you should use scoped_ptr or shared_ptr.
If you have some unexplained phobia against STL or boost, you can always pull your own smart pointer class with relative ease (if you don't require super exception safety).
This is a all about ownership.
You need to decide who has ownership (or is there shared ownership).
Basically passing pointers is a very bad idea and NOT very C++ like (this is basically a C interface as there is no concept of ownership). In a C++ program you should define your interfaces (functions) with a very clear sense of ownership transfer.
You have a couple of options.
The function does not have ownership and can not be NULL.
In this case you should pass by reference
The function does not have ownership but may be NULL.
Pass as a pointer and add comments that ownership is not being transferred. This is the worst situation and you should try and avoid this as the semantics are not clearly expressed by the code.
The function takes ownership.
In this case I would suggest using std::auto_ptr as it explicitly indicates that ownership is being transferred to the function.
The function shares ownership.
In this case some form of shared smart pointer like boost::shared_ptr or std::tr1::shared_ptr
In your case I would suggest 1 or 2 depending on the situation.
It is obviously that the function can not delete the pointer as it sometimes may not have ownership. Thus the ownership remains on the side of the caller. So the caller must call the delete as appropriate. Hopefully via some smart pointer mechanism.
You need to decide on the ownership, either:
Caller owns object: object is LOANED to function, Caller is responsible for allocation and deletion.
Function owns object: object is DONATED to function, Caller is responsible for allocation, callee (function) is responsible for deletion.
Use a reference counting via a shared pointer to avoid the problem.
( 2 is ugly because it means that different code is responsible for allocation and deletion, but that might be the correct solution for your case - it also means making copies of the argument if the caller wants to keep the object).
Both of these are valid options in the c++ syntax sense, but I'd argue that the second option is bad software design in almost all cases, and allowing both options in one function might even be bad software design in all cases.
Either the calling class creates the object, calls the method, and deletes the object,
or the calling class creates the object, calls the methon, and expects the method to delete the object.
I see no good reason why both options should be considered reasonable in one method call. It should be clear from documentation or comments which version the method uses, and it is then up to the developer to use that method, or suffer the consequences.
The common behavior is for functions neither to create nor to destroy objects. However, there are functions that do. Common jargon is "sources and sinks". A very useful convention, if you're not using more versatile smart pointers, is to use std::auto_ptr<T> for both sources and sinks. A "source" function returns the object created as an auto_ptr<T>, whereas a sink takes an argument of type auto_ptr<T>.
The benefit is that even if you forget the return value of a source function, you won't have a memory leak. At the end of the statement, the returned auto_ptr destroys the object returned. And similarly, it is obvious that the argument passed in to a void sink(auto_ptr<T> unreferenced) { } will be destroyed before sink returns.
The memory should be freed by its owner. Usually, the owner is the entity that allocated the memory, but in some cases you may allow ownership to be transferred.
void foo() {
myClass* p = new myClass(); // foo owns the pointer, so foo should release it again
}
void foo() {
boost::shared_ptr<myClass> p = new myClass(); // foo allocates the memory, but *transfers* ownership to the smart pointer. The smart pointer is now responsible for freeing the object. (This is true for all types of smart pointers, including boost::scoped_ptr, std::auto_ptr or the C++0x std::unique_ptr.
}
void foo() {
ScopedMyClass x; // ScopedMyClass is some class wrapper which *internally* calls `new myClass`, and so owns the allocation and is responsible for freeing it before the end of the wrapper class' lifetime.
}
In your case specifically, if myMethod doesn't allocate the memory, then it should not free the memory either.
As for how to handle this:
myMethod(new myClass(...));
Just don't do that. If you allocate memory, you need to take ownership of it. Store the pointer first, so you can delete the memory:
myClass* p = new myClass(...);
myMethod(p);
delete p;
or even better, *don't dynamically allocate the object in the first place, eliminating the question of ownership:
myMethod(myClass(...));
I can't comment yet but .. While I would normally argue strongly for the 'creator owns it' paradigm (can you really prove anything else correct?) , I think that the insistence on having the
myMethod(new myClass(...));
usage pretty much requires ownership to be transferred. Perhaps it would be prudent to ask what you're attempting to accomplish with this usage, and could it be handled in another way? Like an overload that takes a reference to the temporary instead of a pointer?
myMethod(myClass& a) { return myMethod(&a); }
myMethod(myClass(...))
Well, I suppose I'll add my little stone to the edifice... though I am not sure it will even be read.
This is a matter of ownership of the memory, it is the role of your interface to convey this meaning: "Will this method take ownership or not".
To better express ownership, it is usually bad to use raw pointers. The STL has the bastard auto_ptr which is better suited to the task (I am waiting for the upcoming unique_ptr rather impatiently there).
For a method, there are several ways to accept parameters:
// Value
void method(T);
// Reference
void method(T&);
// Pointer
void method(T*);
// Smart Pointer
void method(std::auto_ptr<T>);
I skipped the cv-qualification bit because it's irrelevant there.
The point is that out of these 4 solutions, the intent is clear:
Value / Reference / Pointer: the caller is responsible for the memory
auto_ptr the method takes ownership of the memory, this means that the caller cannot use the variable afterward
std::auto_ptr myT = std::auto_ptr(new T());
method(myT);
assert(myT.get() == 0); // myT does not hold anything any longer!
Of course, that's why auto_ptr is a wild beast out there, since it does not respect the convention that a copying an object leaves the copied object apparently unchanged: normally all the public methods should give the same result before and after, reference counting being a corner case here if you expose it.
So, your interface should be clearer if whether or not the caller should expect the method to take ownership or not, a simple way is to use overloading.
void method(T*); // do something
void method(std::auto_ptr<T> p)
{
method(p.get());
}
Easy enough, you are now clear on who handles the memory!
With the same reasonment you can also use this overloading trick to automatically check a pointer for nullity.
void method(T&); // do something
void method(T* p)
{
if (p) method(*p); else throw NullPointer("method");
}
But I would avoid abusing the trick, you'll end up with thousands of methods.
So just remember: ownership semantic is best expressed in CODE rather than in comments.
Which you will immediately mix with Use RAII to manage resources which means here that you should never allocate memory to a raw pointer: use a smart pointer to express ownership of the resource, and a raw pointer to point to existing objects you do not own (and that might possibly be null, otherwise a reference is better ;) ).
What is the best practice when returning a smart pointer, for example a boost::shared_ptr? Should I by standard return the smart pointer, or the underlying raw pointer? I come from C# so I tend to always return smart pointers, because it feels right. Like this (skipping const-correctness for shorter code):
class X
{
public:
boost::shared_ptr<Y> getInternal() {return m_internal;}
private:
boost::shared_ptr<Y> m_internal;
}
However I've seen some experienced coders returning the raw pointer, and putting the raw pointers in vectors. What is the right way to do it?
There is no "right" way. It really depends on the context.
You can internally handle memory with a smart pointer and externally give references or raw pointers. After all, the user of your interface doesn't need to know how you manage memory internally. In a synchronous context this is safe and efficient. In an asynchronous context, there are many pitfalls.
If you're unsure about what to do you can safely return smart pointers to your caller. The object will be deallocated when the references count reaches zero. Just make sure that you don't have a class that keeps smart pointers of objects for ever thus preventing the deallocation when needed.
As a last note, in C++ don't overuse dynamically allocated objects. There are many cases where you don't need a pointer and can work on references and const references. That's safer and reduces the pressure on the memory allocator.
It depends on what the meaning of the pointer is.
When returning a shared_pointer, you are syntactically saying "You will share ownership of this object", such that, if the the original container object dies before you release your pointer, that object will still exist.
Returning a raw pointer says: "You know about this object, but don't own it". It's a way of passing control, but not keeping the lifetime tied to the original owner.
(in some older c-programs, it means "It's now your problem to delete me", but I'd heavily recommend avoiding this one)
Typically, defaulting to shared saves me a lot of hassle, but it depends on your design.
I follow the following guidelines for passing pointers arguments to functions and returning pointers:
boost::shared_ptr
API and client are sharing ownership of this object. However you have to be careful to avoid circular references with shared_ptr, if the objects represent some kind of graph. I try to limit my use of shared_ptr for this reason.
boost::weak_ptr / raw pointer
API owns this object, you are allowed share it while it is valid. If there is a chance the client will live longer than the api I use a weak_ptr.
std::auto_ptr
API is creating an object but the client owns the object. This ensures that the returning code is exception safe, and clearly states that ownership is being transferred.
boost::scoped_ptr
For pointers to objects stored on the stack or as class member variables. I try to use scoped_ptr first.
Like all guidelines there will be times when the rules conflict or have to be bent, then I try to use intelligence.
I typically return "owning"/"unique" smart pointers from factories or similar to make it clear who is responsible for cleaning up.
This example https://ideone.com/qJnzva shows how to return a std::unique_ptr that will be deleted when the scope of the variable that the caller assigns the value to goes out of scope.
While it's true that the smart pointer deletes its own pointer, the lifetime of the variable holding the smart pointer is 100% controlled by the caller, so the caller decides when the pointer is deleted. However, since it's a "unique" and "owning" smart pointer, no other client can control the lifetime.
I would never return a raw pointer, instead I would return a weak_ptr to tell the user of the pointer that he doesn't have the control over the resource.
If you return a weak_ptr its very unlikely that there will be dangling pointers in the application.
If there is a performance problem I would return a reference to the object and a hasValidXObject method.
In my opinion, in C++, you should always have to justify the use of an unguarded pointer.
There could be many valid reasons: a need for very high performance, for very low memory usage, for dealing with legacy libraries, because of some issue with the underlying data structure the pointer is storing. But [dynamically allocated] pointers are somewhat 'evil', in that you have to deallocate the memory at every possible execution path and you will almost certainly forget one.
I wouldn't put raw pointers in vectors.
In case they use auto_ptr or boost::scoped_ptr, they can't use (or return) anything but raw pointers. That could explain their way of coding, i guess.
depends on your goals.
blindly returning smart ptr to internal data might not be a good idea (which is very sensitive to the task you're trying to solve) - you might be better off just offering some doX() and doY() that use the pointer internally instead.
on the other hand, if returning the smart ptr, you should also consider that you'll create no mutual circular references when objects end up unable to destroy each other (weak_ptr might be a better option in that case).
otherwise, like already mentioned above, performance/legacy code/lifetime considerations should all be taken into account.
const boost::shared_ptr &getInternal() {return m_internal;}
This avoids a copy.
Sometimes you'll like to return a reference, for example:
Y &operator*() { return *m_internal; }
const Y &operator*() const { return *m_internal; }
This is good too only if the reference will be used and discarded inmediately.
The same goes for a raw pointer.
Returning a weak_ptr is also an option.
The 4 are good depending on the goals. This question requires a more extensive discussion.
While learning different languages, I've often seen objects allocated on the fly, most often in Java and C#, like this:
functionCall(new className(initializers));
I understand that this is perfectly legal in memory-managed languages, but can this technique be used in C++ without causing a memory leak?
Your code is valid (assuming functionCall() actually guarantees that the pointer gets deleted), but it's fragile and will make alarm bells go off in the heads of most C++ programmers.
There are multiple problems with your code:
First and foremost, who owns the pointer? Who is responsible for freeing it? The calling code can't do it, because you don't store the pointer. That means the called function must do it, but that's not clear to someone looking at that function. Similarly, if I call the code from somewhere else, I certainly don't expect the function to call delete on the pointer I passed to it!
If we make your example slightly more complex, it can leak memory, even if the called function calls delete. Say it looks like this: functionCall(new className(initializers), new className(initializers)); Imagine that the first one is allocated successfully, but the second one throws an exception (maybe it's out of memory, or maybe the class constructor threw an exception). functionCall never gets called then, and can't free the memory.
The simple (but still messy) solution is to allocate memory first, and store the pointer, and then free it in the same scope as it was declared (so the calling function owns the memory):
className* p = new className(initializers);
functionCall(p);
delete p;
But this is still a mess. What if functionCall throws an exception? Then p won't be deleted. Unless we add a try/catch around the whole thing, but sheesh, that's messy.
What if the function gets a bit more complex, and may return after functionCall but before delete? Whoops, memory leak. Impossible to maintain. Bad code.
So one of the nice solutions is to use a smart pointer:
boost::shared_ptr<className> p = boost::shared_ptr<className>(new className(initializers));
functionCall(p);
Now ownership of the memory is dealt with. The shared_ptr owns the memory, and guarantees that it'll get freed. We could use std::auto_ptr instead, of course, but shared_ptr implements the semantics you'd usually expect.
Note that I still allocated the memory on a separate line, because the problem with making multiple allocations on the same line as you make the function call still exists. One of them may still throw, and then you've leaked memory.
Smart pointers are generally the absolute minimum you need to handle memory management.
But often, the nice solution is to write your own RAII class.
className should be allocated on the stack, and in its constructor, make what allocations with new are necessary. And in its destructor, it should free that memory. This way, you're guaranteed that no memory leaks will occur, and you can make the function call as simple as this:
functionCall(className(initializers));
The C++ standard library works like this. std::vector is one example. You'd never allocate a vector with new. You allocate it on the stack, and let it deal with its memory allocations internally.
Yes, as long as you deallocate the memory inside the function. But by no means this is a best practice for C++.
It depends.
This passes "ownership" of the memory to functionCAll(). It will either need to free the object or save the pointer so that it can be freed later. Passing the ownership of raw pointers like this is one of the easiest ways to build memory issues into your code -- either leaks or double deletes.
In C++ we would not create the memory dynamically like that.
Instead you would create a temporary stack object.
You only need to create a heap object via new if you want the lifetime of the object to be greater than the call to the function. In this case you can use new in conjunction with a smart pointer (see other answers for an example).
// No need for new or memory management just do this
functionCall(className(initializers));
// This assumes you can change the functionCall to somthing like this.
functionCall(className const& param)
{
<< Do Stuff >>
}
If you want to pass a non const reference then do it like this:
calssName tmp(initializers);
functionCall(tmp);
functionCall(className& param)
{
<< Do Stuff >>
}
It is safe if the function that you are calling has acceptance-of-ownership semantics. I don't recall a time where I needed this, so I would consider it unusual.
If the function works this way, it should take its argument as a smart pointer object so that the intent is clea; i.e.
void functionCall(std::auto_ptr<className> ptr);
rather than
void functionCall(className* ptr);
This makes the transfer of ownership explicit, and the calling function will dispose of the memory pointed to by ptr when execution of the function falls out of scope.
This will work for objects created on the stack, but not a regular pointer in C++.
An auto pointer maybe able to handle it, but I haven't messed with them enough to know.
In general, no, unless you want to leak memory. In fact, in most cases, this won't work, since the result of
new T();
in C++ is a T*, not a T (in C#, new T() returns a T).
Have a look at Smart Pointers or A garbage collector for C and C++.