What's new

detecting memory allocation error under c++

cufunha

New member
A emulator uses lots of system memory for everything. Sometimes, the system might be overloaded, and we get a memory error when trying to allocate memory for the emu. Take a look at this code:

long *myArr;

..... inside some function ......
myArr = new long[64*1024*1024]; //allocate 64MB of RAM memory

in most of the cases, this code will work, but, sometimes, we'll get an error from windows (when physical ram memory is too low, windows denies memory requests from other applications until some part of the physical memory is free, even if virtual memory is not that full). How can I detect this windows deny in order to prevent my application from shutting down?
 

aprentice

Moderator
When allocating that much memory you should be using malloc, for example:

unsigned char *mem;
mem = (unsigned char*)malloc(64 * (1024*1024));
if(!mem) MessageBox(NULL,"error allocating memory",NULL,NULL);

Anyway, you seem to lack programming experience, I recommend you first learn the programming language before starting your emulator, and it would be a good idea to use msdn to look up stuff before spamming our boards with an insane amount of simple questions.

edit: also, since long is 4 bytes wide, your allocating 256MB not 64MB..
myArr = new long[64*1024*1024]; //allocate 64MB of RAM memory <- wrong
 
Last edited:

zenogais

New member
apprentice:

In c++ when you allocate memory an exception is thrown if the allocation failed. You handle the exception specifically if you include the header <new>. Just google std::bad_alloc.
 

smcd

Active member
if you want to be "lazy" in C++ and treat it like you do in C, do this:
Code:
#include<new>
...
long *ptr = new(std::nothrow) long[5*6*7];
if(!ptr)
{
    error_stuff();
}
 

Doomulation

?????????????????????????
aprentice said:
When allocating that much memory you should be using malloc, for example:

unsigned char *mem;
mem = (unsigned char*)malloc(64 * (1024*1024));
if(!mem) MessageBox(NULL,"error allocating memory",NULL,NULL);

Anyway, you seem to lack programming experience, I recommend you first learn the programming language before starting your emulator, and it would be a good idea to use msdn to look up stuff before spamming our boards with an insane amount of simple questions.

edit: also, since long is 4 bytes wide, your allocating 256MB not 64MB..
myArr = new long[64*1024*1024]; //allocate 64MB of RAM memory <- wrong
Erm, just so you know, new / delete uses malloc for allocation. Afaik, there shouldn't be any problem using new, even for big allocations.
Even so, I'd actually avoid doing many allocations. Do one big allocation at the start of the emulator to accomondate for the emu needs. Allocating memory is a time consuming process.

Oh yeah and new returns NULL if allocation fails for some reason.
 

smcd

Active member
Doomulation said:
Oh yeah and new returns NULL if allocation fails for some reason.

No it doesn't unless you tell it to! References:
The C++ Programming Language said:
What happens when new can find no store to allocate? By default, the allocator throws a bad_alloc exception (for an alternative see ch 19.4.5).
C++ Standard said:
3.7.3.1 Allocation functions [basic.stc.dynamic.allocation]
3. An allocation function that fails to allocate storage can invoke the currently installed new_handler
(18.4.2.2), if any.
[Note: A programsupplied
allocation function can obtain the address of the currently
installed new_handler using the set_new_handler function (18.4.2.3). ] If an allocation function
declared with an empty exceptionspecification
(15.4), throw(), fails to allocate storage, it shall return a
null pointer. Any other allocation function that fails to allocate storage shall only indicate failure by throwing
an exception of class std::bad_alloc (18.4.2.1) or a class derived from std::bad_alloc.

So, to just do it once, use new(std::nothrow), or you can also use #include<new> set_new_handler() (pp129, 576) and set the new_handler to 0, this should make all allocations return NULL on unsuccessful attempts.
 
Last edited:

aprentice

Moderator
zenogais said:
apprentice:

In c++ when you allocate memory an exception is thrown if the allocation failed. You handle the exception specifically if you include the header <new>. Just google std::bad_alloc.

Why should i google bad_alloc, i don't code in c++ :p

edit: and since when do we allocate memory in long's, memory is handled as a char in todays world :p
 
Last edited:

smcd

Active member
the new allocator automatically allocates the appropriate size based on the type to be allocated. in C you'd need to do sizeof(type) * num_to_allocate, you had a point as to why was he doing a long pointer and expecting to get 64MB using new.
 

zenogais

New member
aprentice said:
Why should i google bad_alloc, i don't code in c++ :p

edit: and since when do we allocate memory in long's, memory is handled as a char in todays world :p

Well seeing as how the post's topic was memory allocation in c++ I was just wondering if you were trying to make a point about c++ allocation errors using c code.
 

Doomulation

?????????????????????????
sethmcdoogle said:
No it doesn't unless you tell it to! References:
It does indeed, if you simply use new without including any of that new stuff libraries. NULL is returned because it was unable to allocate the memory and thus have no pointer.

I've been using new for a long time, I should know. Besides, memory allocation should almost never fail unless there is some problems in your app. And then you'll probably get an acces violation since the pointer is NULL.
 

zenogais

New member
Doomulation said:
It does indeed, if you simply use new without including any of that new stuff libraries. NULL is returned because it was unable to allocate the memory and thus have no pointer.

I've been using new for a long time, I should know. Besides, memory allocation should almost never fail unless there is some problems in your app. And then you'll probably get an acces violation since the pointer is NULL.

No, you are still incorrect. NULL is not necessarily returned, and malloc is not necessarily used in the body of the global new operator. These are all assumptions, and bad ones at that. The standard merely says what sethmcdoogle pointed out. The new_handler is always called when a memory allocation fails, and by default throws an std::bad_alloc, this is why if you want more specific information you should set a new new_handler.
 

Doomulation

?????????????????????????
Afaik, no. In my version of NET (which should be the same as all!), it merely returns a NULL pointer. And I've myself stepped through the new operator to see why the allocation failed, and it was using malloc.

And from what I remember is that also some examples check for a NULL pointer after allocating memory with new. But that's old, and I can't remember where I've seen such.
 

Slougi

New member
Just because Microsoft chose to use malloc for memory allocations with new, doesn't mean everybody does. As was said, all you can assume is what is specified in the C++ standard.
 

Top