473,396 Members | 1,914 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

Throwing bad_alloc when calling new on large class

First off, I am not sure if this belongs in this group or the C# group. It
seems more like a C++ problem to me. Anyways...

I have a C# project which links in an unmanaged C++ DLL, both built with
VS2005. I am having a problem where the C# program is making a call into the
C++ DLL which new's a large class. For a class of a certain size the new is
failing. Here's somewhat of an example of what I am doing:

// Start C# program code
public enum MyTypes
{
TYPE1 = 0,
TYPE2 = 1
}

[DllImport("MyDll.dll")]
public static extern void UnmanagedFunc(MyTypes PassedType);

MyTypes funcArg = MyTypes.TYPE1;
UnmanagedFunc(funcArg);
// End C# program code

// Start unmanaged C++ DLL code
// This next line is from the class declaration and initialized to NULL in
the
// class constructor, I just haven't shown that here.
ParentClass *ClassPtr_;

void UnmanagedClass::UnmanagedFunc(MyTypes PassedType)
{
if(ClassPtr_)
{
delete ClassPtr_;
}

switch(PassedType)
{
case TYPE1:
ClassPtr_ = new Class1();
break;
case TYPE2:
default:
ClassPtr_ = new Class2();
break;
}
}
// End unmanaged C++ DLL code

A few things to note. I left out the C++ wrapper code which wraps the
unmanaged call to this function to the managed call--there is no issue with
that code. Class1 and Class2 are inherited from ParentClass. Class1's size
is around 150 MB, while Class2 is around 200 MB. Both classes have large
static arrays in them, but Class2 has more arrays, which makes up the 50 MB
difference.

When UnmanagedFunc is called with the parameter MyTypes::TYPE1, there is no
problem. However when MyTypes::TYPE2 is used, then the new call throws
std::bad_alloc. I have plenty of physical memory and virtual memory
available, so that should not be a problem. My program size (according to
Task Manager and Performance Monitor) is about 750 MB at the point before
attempting the new. This brings up a few questions in my mind (other than
the obvious, "why doesn't this work?"):

Are unmanaged and managed heaps shared within the context of a process? If
not, could one heap (in this case the managed heap) reserve more space than
it needs such that the other heap (in this case the unmanaged heap) doesn't
have enough heap to new the larger class?

Is there a way to specify the size of the heap in C# (since there is no way
to specify heap size for a DLL that I am aware of)?

If this is a problem with fragmentation, is there any way to "defragment"
the heap space so I am able to allocate the contiguous block that I need?

Many thanks in advance.
-SteveZ
Jan 16 '08 #1
7 1903
A few things to note. I left out the C++ wrapper code which wraps the
unmanaged call to this function to the managed call--there is no issue with
that code. Class1 and Class2 are inherited from ParentClass. Class1's size
is around 150 MB, while Class2 is around 200 MB. Both classes have large
static arrays in them, but Class2 has more arrays, which makes up the 50 MB
difference.
Those are pretty big classes. Remember, you are asking the operating system to allocate 200 MB of contiguous memory. Because of
memory fragmentation, this simply may not be available. This is probably a very valid exception. I don't mean to be critical, but
requiring this much contiguous memory at once is an indication of poor design.

Brian

Jan 16 '08 #2


"Brian Muth" wrote:
A few things to note. I left out the C++ wrapper code which wraps the
unmanaged call to this function to the managed call--there is no issue with
that code. Class1 and Class2 are inherited from ParentClass. Class1's size
is around 150 MB, while Class2 is around 200 MB. Both classes have large
static arrays in them, but Class2 has more arrays, which makes up the 50 MB
difference.

Those are pretty big classes. Remember, you are asking the operating system to allocate 200 MB of contiguous memory. Because of
memory fragmentation, this simply may not be available. This is probably a very valid exception. I don't mean to be critical, but
requiring this much contiguous memory at once is an indication of poor design.

Brian

The context of the application somewhat calls for the use of large classes
like this for various reasons. One of which is that the unmanaged C++ DLL is
targeted for both desktop PC and embedded (non-Windows) platforms. There is
an option of breaking the class down to smaller classes, but that will
increase the context switch performance hit in the embedded environment with
more new calls. I would rather not go down that route.

Not to mention that containing all the structures in those single classes
would add to the readability and maintainability of the code because of how
it is structured. The classes contain large structures which store data from
large images in them--that's the reasoning for the large arrays in the
classes.

I would rather like to know the answer to the question as to why a large
class like that cannot be created on the heap on the Windows platform. Is it
because of poor heap management and having a lot of heap fragmentation? Or
is it because of competing heaps (managed and unmanaged)? It is not a
physical memory issue because the systems I am working with have 3 GB of RAM.
The used system memory of the system is much less than that (per Task
Manager). Is there some boundary as to the size of object which is created
on the heap? These are similar to the questions I had proposed originally
(and the reasoning as to why I proposed them).

Thanks.
-SteveZ

Jan 17 '08 #3

"SteveZ" <St****@discussions.microsoft.comwrote in message news:F5**********************************@microsof t.com...
>

"Brian Muth" wrote:

Not to mention that containing all the structures in those single classes
would add to the readability and maintainability of the code because of how
it is structured. The classes contain large structures which store data from
large images in them--that's the reasoning for the large arrays in the
classes.

I would rather like to know the answer to the question as to why a large
class like that cannot be created on the heap on the Windows platform. Is it
because of poor heap management and having a lot of heap fragmentation?
That's what it is. Unless you are using the /3G switch in your boot.ini file, you are only using 2 GB of physical memory.
Regardless, you only have at best 2 GB of virtual memory per application. You can imagine it doesn't take too many allocations and
deallocations of huge chunks of memory before the system fails to find the 200 MB of contiguous memory you are asking for.

One fairly easy way out is to move to a 64-bit OS. You aren't faced with these upper memory boundaries in that environment.
Otherwise you may be stuck with managing your own heap.
Brian

Jan 17 '08 #4

"Brian Muth" <bm***@mvps.orgwrote in message
news:uO**************@TK2MSFTNGP04.phx.gbl...
>
"SteveZ" <St****@discussions.microsoft.comwrote in message
news:F5**********************************@microsof t.com...
>>

"Brian Muth" wrote:

Not to mention that containing all the structures in those single classes
would add to the readability and maintainability of the code because of
how
it is structured. The classes contain large structures which store data
from
large images in them--that's the reasoning for the large arrays in the
classes.
You mentioned these are static arrays? They shouldn't add to the
per-instance object size at all.
>>
I would rather like to know the answer to the question as to why a large
class like that cannot be created on the heap on the Windows platform.
Is it
because of poor heap management and having a lot of heap fragmentation?

That's what it is. Unless you are using the /3G switch in your boot.ini
file, you are only using 2 GB of physical memory. Regardless, you only
have at best 2 GB of virtual memory per application. You can imagine it
doesn't take too many allocations and
Both these statements are incorrect. 32-bit WinXP uses up to 3.5 GB of
physical memory regardless of the /3G switch. Each application has either
2G or 3G of virtual address space depending on the switch, and each
application can have nearly unlimited virtual memory using file mappings.
deallocations of huge chunks of memory before the system fails to find the
200 MB of contiguous memory you are asking for.

One fairly easy way out is to move to a 64-bit OS. You aren't faced with
these upper memory boundaries in that environment. Otherwise you may be
stuck with managing your own heap.
Brian

Jan 17 '08 #5
Both these statements are incorrect. 32-bit WinXP uses up to 3.5 GB of physical memory regardless of the /3G switch. Each
application has either 2G or 3G of virtual address space depending on the switch, and each application can have nearly unlimited
virtual memory using file mappings.
Thanks for the correction
>
You mentioned these are static arrays? They shouldn't add to the per-instance object size at all.
I'm not convinced the OP actually used to static keyword. If so, this is indeed a surprise, since the actual allocation is probably
quite small, and one wouldn't expect a bad_alloc exception. Perhaps the OP can clarify.

Brian
Jan 17 '08 #6


"Brian Muth" wrote:
Both these statements are incorrect. 32-bit WinXP uses up to 3.5 GB of physical memory regardless of the /3G switch. Each
application has either 2G or 3G of virtual address space depending on the switch, and each application can have nearly unlimited
virtual memory using file mappings.

Thanks for the correction

You mentioned these are static arrays? They shouldn't add to the per-instance object size at all.

I'm not convinced the OP actually used to static keyword. If so, this is indeed a surprise, since the actual allocation is probably
quite small, and one wouldn't expect a bad_alloc exception. Perhaps the OP can clarify.

Brian
Brian is correct. It was a poor choice of words on my part in the OP. I
should have said that they are fixed-size arrays, not static arrays. So they
are allocated each time the class is created with new.

Since I am not using the complete physical address space and I should have
plenty of virutal memory (as indicated by Ben Voigt), I am still confused as
to why the allocation of the class is failing. I should also mention that
this exception occurs on the first occurance of class allocation and is
consistent between program runs. Can the heap be this fragmented every time
I run the program?

Thanks.
-SteveZ

Jan 17 '08 #7

"SteveZ" <St****@discussions.microsoft.comwrote in message
news:1D**********************************@microsof t.com...
>

"Brian Muth" wrote:
Both these statements are incorrect. 32-bit WinXP uses up to 3.5 GB of
physical memory regardless of the /3G switch. Each
application has either 2G or 3G of virtual address space depending on
the switch, and each application can have nearly unlimited
virtual memory using file mappings.

Thanks for the correction
>
You mentioned these are static arrays? They shouldn't add to the
per-instance object size at all.

I'm not convinced the OP actually used to static keyword. If so, this is
indeed a surprise, since the actual allocation is probably
quite small, and one wouldn't expect a bad_alloc exception. Perhaps the
OP can clarify.

Brian

Brian is correct. It was a poor choice of words on my part in the OP. I
should have said that they are fixed-size arrays, not static arrays. So
they
are allocated each time the class is created with new.

Since I am not using the complete physical address space and I should have
plenty of virutal memory (as indicated by Ben Voigt), I am still confused
as
to why the allocation of the class is failing. I should also mention that
this exception occurs on the first occurance of class allocation and is
consistent between program runs. Can the heap be this fragmented every
time
I run the program?
Your virtual address space is pretty fragmented, because dynamic libraries
are compiled to use random locations in the hope of preventing collisions.
(If there were a collision the loader would have to fixup every reference to
code, global variable, etc which adds a lot of overhead to initializing a
DLL).
>
Thanks.
-SteveZ

Jan 18 '08 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Jacek Dziedzic | last post by:
Hi! I accidentally did something like float *ptr = new float; where n was accidentally left uninitialized (and equal to something like -1073372080) and my program coredumped. I always...
5
by: Asfand Yar Qazi | last post by:
Hi, Just wondering, if I do a: std::set_new_handler(std::terminate) I won't have to worry about a std::bad_alloc being thrown when I do a 'new ...' or a 'new(nothrow) ...', right? Its...
21
by: Stephan | last post by:
why does the following code not work???? after compiling and running it will just say killed after all my memory filled up any suggestions? #include <iostream> using namespace std; void...
21
by: mihai | last post by:
People say that is a bad technique to throw exception from constructors; and that the solution would be to create a function _create_ to initialize an object. What about copy constructors? How...
14
by: Mohsen | last post by:
Hello everyone, In my program, I have to define many pointers and when I want to compile my program (in UNIX), it gives me the following error: terminate called after throwing an instance of...
1
by: usenet | last post by:
I wrote some sample code (see below) for nested exception throwing i.e. my catch blocks are throwing exceptions of their own (for simplicity I used standard exceptions). I am getting some...
44
by: Smokey Grindle | last post by:
I have a list box on my form, but I need to databind it to a data table that is a private member of the form's class... so I basically have Public Class MyForm priate m_MyTable as new datatable...
16
upadhyad
by: upadhyad | last post by:
Hi everyone !! i have an interesting problem...hope you people can help. I am coding in C. the code is posted below: here I have a structure with two character vectors. I have to characters....
21
by: Chris M. Thomasson | last post by:
Is it every appropriate to throw in a dtor? I am thinking about a simple example of a wrapper around a POSIX file... ________________________________________________________________________ class...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.