Reputation: 1305
This question is more of a sanity check rather than "please solve my problem". I've recently inherited some code for an application that was written over a couple of decades, by a number of different developers of varying skills. Consequently, trying to make sense of what the code is actually wanting to do is always a bit of a mission in itself.
Anyway, I came across this initialisation pattern time and time again where memory is dynamically allocated, and the result checked soon afterwards. Because this code is in both a stand-alone library and a GUI, the previous developers used a _STANDALONE
macro to check this and handle the error accordingly:
double *myArray = (double *) calloc(length, sizeof(double));
if (myArray == NULL)
{
strcat(message1, "myArray");
#ifdef _STANDALONE
fprintf(stderr, "%s %s\n", message1, message2);
#else
MessageBox(Window, message1, message2, MB_ICONEXCLAMATION);
#endif
exit(EXIT_FAILURE);
}
Note: You can assume message1
and message2
contains a string saying "failed to allocate memory for varible..." and is big enough to have extra gubbins appended to it.
Here comes the sanity check. The most likely reason a memory allocation would fail is that the operating system didn't have any spare. Let's take a look at the error handling code, if we assume there is no more memory spare:
fprintf
may or may not fail depending on the state of internal buffers. I don't know what the function looks like under the bonnet but I'm going to assume its memory requirements are minimal.MessageBox
would result in additional memory allocations because this results in GUI objects being presented on screen. Therefore, surely this would fail and so doesn't achieve what the developer intended.In short, I suggest that this could be better handled but it's not so obvious the correct path to take.
Upvotes: 2
Views: 777
Reputation: 90174
Just because calloc
failed doesn't mean that the error handling paths will fail too.
calloc
possibly failed because the request was ridiculous. For example, if length * sizeof (double)
overflows, calloc
should fail. Or even perhaps the request is an unreasonable amount of memory in the first place even if there is no overflow. In these circumstances, there might be plenty of free memory for use by fprintf
or MessageBox
.
Without knowing the implementations of fprintf
and MessageBox
, you cannot know for certain whether they will require additional memory allocations. Perhaps the system already reserved some memory for them for the purpose of showing error messages in low-memory situations.
I wouldn't worry about fprintf
and MessageBox
failing. If your system truly does not have enough free memory to deal with fprintf
or MessageBox
, it's probably going to be freaking out in plenty of other ways. Terminating in the face of such extreme memory pressure is pretty reasonable.
Upvotes: 2
Reputation: 96326
One way to tackle this problem is to pre-allocate some memory which will never be used.
When you run out of memory, you free
this area, so hopefully your error handler will have enough memory to finish its job.
Upvotes: 0
Reputation: 1051
The big question here is the typical size of "length". In case the length regularly is very high (let's say 1MB and up) it's pretty safe to assume that you still have enough memory for a simple message box even if the allocation failed. (and the actual goal of the check is to protect against these very large allocations).
In case the array is usually small, you better don't show any boxes. (What you could do is to preallocate all necessary resources to show the window. not sure that's possible with a message box however).
Upvotes: 0