I've never been taught a specified way of how to handle bad allocations of dynamically allocated variables. I've taken the time to come up with a solution that will prevent the program from having to terminate in case of a bad allocation. And at the same time, I won't have have to create a lot of alternate paths in my code in case a bad allocation does occur.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
//Declare the pointer
bool* foo;
try
{
//Try to allocate it dynamically
foo = newbool;
}
//If it doesn't work
catch (std::bad_alloc& x)
{
//Create a non-pointer variable of same type
bool bar;
//Have the first pointer point to the new variable
foo = &bar;
}
//Whether the variable is dynamically allocated or not, calling it will be the same
*foo = false;
What do you think? Is this a good way to handle things in case memory can't be allocated dynamically?
Side note:
Am I using jargon correctly? I've been told on other forum posts that I have a tendency to misuse keywords. Let me know if I spoke something that was out of place.
bar will be destructed on line 16, and so foo will be a dangling pointer.
Unless you are allocating a huge amount of memory that you know has a chance to fail, you should never be concerned about running out of memory - that's the user's fault for not giving your program enough memory to run.
That is not correct. You are assigning foo to point to bar, which goes out of scope and ceases to exist on line 16, so line 19 won't do at all. If you actually can handle the allocation failure somehow, I suppose the exception catching method is a good one, but I think you may be going about this the wrong way.
If you can handle the situation with a "normal" variable, why are you even dynamically allocating in the first place? Just declare a variable without automatic storage duration and use it instead of a pointer.
In general, I'd even say that running out of memory is a good reason to terminate the program; if you run out of memory you are going to be very limited in what you can do.
bar will be destructed on line 16, and so foo will be a dangling pointer.
I see. So is there no way to make it so that the pointer does in fact point to a variable in the catch expression?
Unless you are allocating a huge amount of memory that you know has a chance to fail, you should never be concerned about running out of memory
I appreciate your re-assurance. I'm just interested in seeing how I can make a program as memory efficient as possible. Though I do understand and agree with what you're saying.
I see. So is there no way to make it so that the pointer does in fact point to a variable in the catch expression?
There is, and you are doing it. The problem is that the automatic variable bar you declare inside the catch block is destructed when the block ends, not that the pointer isn't being assigned properly.
Edit: The proper term would be "catch block" rather than "catch expression".
If you can handle the situation with a "normal" variable, why are you even dynamically allocating in the first place? Just declare a variable without automatic storage duration and use it instead of a pointer.
I guess you are right. I've been so obsessed with conserving memory that I've lost track and didn't take the time to realize that I'm not saving that much memory to begin with...
In general, I'd even say that running out of memory is a good reason to terminate the program; if you run out of memory you are going to be very limited in what you can do.
Lesson learnt. Much appreciated :)
The problem is that the automatic variable bar you declare inside the catch block is destructed when the block ends, not that the pointer isn't being assigned properly.
So the only way I could make use of foo, even if it isn't allocated, would be for bar to be a variable in the function scope. The approach I was going for when declaring the variable in the catch block would be that the variable would only be declared if the allocation didn't work. Having to declare bar when I know that I might not need it (in case allocation does work) ruins the entire point of doing all this.
Is there a way to have a variable be declared only if the allocation doesn't work, and still have full function scope?
If a process expects to utilize a minimum amount of memory to do its task, the correct response is:
fail.
(1) If that process is your program, let the program terminate.
(2) If that process is a subroutine in your program (say, the user asks you to load a too-big file or something), wrap the attempt into a try..catch block so that when the subroutine fails it can complain to the user that it could not complete the requested action (due to insufficient memory).
Alas, this is the current state of memory management for most programs.
(In a secure computing environment, there are much more stringent requirements, but I don't think you need to worry about that deep-end stuff yet...)
Also, I hope (and presume) that allocating a single bool on the heap was just an example. Don't do that.
C++ is designed so you really don't have to be handling memory with raw new and delete operations. Use std::unique_ptr and std::shared_ptr. See this recent post and followup by JLBorges: http://www.cplusplus.com/forum/general/140493/#msg742595
When do you suggest it would be the smartest to make use of allocating variables on the heap?
Only put stuff on the heap if you need to. Generally there are 2 times you'd want to do this:
1) If you need polymorphism
2) If the object/array is excessively large (like 100 KB or more)
For pretty much all other times, you're better off putting your vars on the stack or using a container class like vector.
EDIT:
To clarify, I'm speaking very generally. There are always exceptions and you should use your best judgement. Sometimes you might need heap allocation for some other reason.
The point I'm trying to make is that it shouldn't be preferred.
4) If you don't know how big an array needs to be until run-time.
As Disch pointed out this can often be handled with a std::vector, but the choice of allocating a variable sized array on the heap verses using a vector is a design decision that you need to make.
4) If you don't know how big an array needs to be until run-time.
Technically, stack allocation doesn't have this limitation. Just for fun, can you think of a way to allocate a variably-sized sequence on the stack without undefined behavior?