-
July 24th, 2010, 11:15 AM
#1
A coding style question
Suppose I have a function in which there is multiple return statements and also I allocate a memory in heap at the beginning of function, so I need to deallocate the memory in every return statement so as not to leak the memory in every situation. Not only there is redundant delete statements but also it is error prone. For example, what if I forget to call the delete before one of return statements? I wander if there is any elegant solution to approach this issue? Thanks.
-
July 24th, 2010, 11:21 AM
#2
Re: A coding style question
An elegant solution is to use a smart pointer or container, as appropriate.
-
July 24th, 2010, 11:22 AM
#3
Re: A coding style question
Originally Posted by LarryChen
Suppose I have a function in which there is multiple return statements and also I allocate a memory in heap at the beginning of function, so I need to deallocate the memory in every return statement so as not to leak the memory in every situation. Not only there is redundant delete statements but also it is error prone. For example, what if I forget to call the delete before one of return statements? I wander if there is any elegant solution to approach this issue? Thanks.
Yes, the solution is to use classes that automatically clean up on destruction, such as vector, and not just allocate raw memory.
In other words, RAII.
Regards,
Paul McKenzie
-
July 24th, 2010, 11:45 AM
#4
Re: A coding style question
Ok, here is an approach using RAII. But since I allocate an array of memory so I don't know how to use smart pointer to do the similar thing. Does smart pointer work with array of memory?
Code:
class B
{
public:
B(int size)
{
data = new int[size];
}
~B()
{
delete[] data;
}
int& operator[](int index)
{
return data[index];
}
private:
int* data;
};
bool UseArray(int a[], int size)
{
//int* b = new int[size];
B b(size);
if(...)
{
//delete[] b;
return true;
}
...
if(...)
{
// delete[] b;
return true;
}
//delete[] b;
return false;
}
Any comments are welcome.
-
July 24th, 2010, 11:51 AM
#5
Re: A coding style question
Originally Posted by LarryChen
Ok, here is an approach using RAII.
Why did you not reach for std::vector instead of rolling your own solution?
Originally Posted by LarryChen
But since I allocate an array of memory so I don't know how to use smart pointer to do the similar thing. Does smart pointer work with array of memory?
It depends on the smart pointer and how you use it, but generally a container would be a more appropriate solution.
-
July 24th, 2010, 11:59 AM
#6
Re: A coding style question
I agree here stl container is more appropriate. But if I want to use auto_ptr, how can I allocate an array of memory by using it? Thanks.
Originally Posted by laserlight
Why did you not reach for std::vector instead of rolling your own solution?
It depends on the smart pointer and how you use it, but generally a container would be a more appropriate solution.
-
July 24th, 2010, 12:06 PM
#7
Re: A coding style question
Originally Posted by LarryChen
But if I want to use auto_ptr, how can I allocate an array of memory by using it?
You cannot, at least not without invoking undefined behaviour when it comes to destroying the array.
-
July 24th, 2010, 12:14 PM
#8
Re: A coding style question
So auto_ptr doesn't work with array of memory?
Originally Posted by laserlight
You cannot, at least not without invoking undefined behaviour when it comes to destroying the array.
-
July 24th, 2010, 12:23 PM
#9
Re: A coding style question
Originally Posted by LarryChen
So auto_ptr doesn't work with array of memory?
Yes. If you really insist, use something like boost::scoped_array, or a smart pointer with a custom deleter.
-
July 24th, 2010, 12:32 PM
#10
Re: A coding style question
Originally Posted by LarryChen
I wander if there is any elegant solution to approach this issue? Thanks.
Since you keep using it, I feel I need to point out the correct word here is "wonder".
-
July 24th, 2010, 12:35 PM
#11
Re: A coding style question
Originally Posted by LarryChen
So auto_ptr doesn't work with array of memory?
nope.
Look into boost::scoped_array, or (boost/tr1/std)::shared_pointer can handle arrays. At least, the source code says so, but I'm not 100% sure what the standard says.
Worst case scenario, shared_pointer can take a "deleter" argument, giving it the power to destroy/release anything, regardless of method of destruction.
Or, use a container, they are RAII too. And they allocate on the heap too, so you have no reason not to use one.
Is your question related to IO?
Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.
-
July 24th, 2010, 12:44 PM
#12
Re: A coding style question
How'd I implement a custom deleter for smart pointer? I searched on the web but couldn't find any good resource on that matter. Thanks.
Originally Posted by laserlight
Yes. If you really insist, use something like boost::scoped_array, or a smart pointer with a custom deleter.
-
July 24th, 2010, 12:49 PM
#13
Re: A coding style question
Thanks for pointing it out.
Originally Posted by GCDEF
Since you keep using it, I feel I need to point out the correct word here is "wonder".
-
July 24th, 2010, 12:49 PM
#14
Re: A coding style question
Originally Posted by LarryChen
I searched on the web but couldn't find any good resource on that matter.
hmm... I do not really like using this, but in this case I find your claim very difficult to believe since it was trivial for me to find a reasonably good resource on this: custom deleter.
-
July 24th, 2010, 03:34 PM
#15
Re: A coding style question
Here's a class I use occasionally.
Code:
enum deallocator {
FREE,
DELETE,
ARRAY
};
#define AUTODELETE(type, name, value, destruc)\
type * name = value; AutoDelete<type> autoclean##name(name, destruc);
template <typename T>
class AutoDelete {
public:
AutoDelete(T * ptr, deallocator d){
myptr = ptr;
mydestroy = d;
}
~AutoDelete(void){
switch (mydestroy){
case FREE:
free(myptr);
break;
case DELETE:
delete myptr;
break;
case ARRAY:
delete[] myptr;
break;
}
}
private:
T * myptr;
deallocator mydestroy;
};
You can use it like this:
Code:
void foo(void){
AUTODELETE(int, array, new int[50], ARRAY);
cout << array[5] << endl;
AUTODELETE(int, array2, (int*)malloc(50 * sizeof(int)), FREE);
}
Of course, it's good to specialize different wrappers for different types of destructors.
If you'd like I have a complete library of automatic wrappers if you'd like me to post them.
Last edited by ninja9578; July 24th, 2010 at 03:37 PM.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|