Code Newbie
News     Forums     Search     Members     Sign Up    

My Code Newbie
Username

Password

Articles/Snippets
ASP Classic
ASP.NET
C
C#
C++
HTML / CSS
Java
Javascript
Linux / BSD
Perl
PHP
Python
Ruby
SQL
VB 6
VB.NET

C.N. Friends
  Planet Rome

Link to Us!
Code Newbie
  Code Newbie
    forums
Old 09-16-2005, 07:18 AM   #1 (permalink)
TheSheep
Registered User
 
TheSheep's Avatar
 
Join Date: Mar 2005
Location: UK
Posts: 11
TheSheep is on a distinguished road
Send a message via ICQ to TheSheep Send a message via AIM to TheSheep Send a message via MSN to TheSheep Send a message via Yahoo to TheSheep
Question new fails, no exception, no handler

Code:
Code:
int MyNewHandler( size_t size )
{
puts("[MyNewHandler] Allocation error!");

return 0; //abort
}

void TryMemAlloc()
{
unsigned char *c;

puts("[TryMemAlloc] Started......");

_set_new_handler(MyNewHandler);

try
	{
	c=new unsigned char;
	}
catch(...)
	{
	puts("[TryMemAlloc] Exception thrown!");
	}
if(c==0)
	puts("[TryMemAlloc] char not allocated!");
else
	printf("[TryMemAlloc] char allocated at %p.\n",c);

puts("[TryMemAlloc] Done");
}
Output:
Code:
[TryMemAlloc] Started......
[TryMemAlloc] char not allocated!
[TryMemAlloc] Done
As you can see, new fails but gives no indication that it's out of memory by throwing an exception (which AFAIK it shouldn't do when I set up my own handler, OK) or calling MyNewHandler. And I don't have any reason to think it would run out of memory either, especially when allocating 1 byte!!
Obviously I'm not doing all this just to allocate a byte - the same problem occurs when trying to dynamically allocate a class I've made.

Compiled using MS VC++ 5.0, non-MFC Win32 DLL, multithreaded (2 threads).


Edit - I appreciate it's preferable to post full compilable code but it's not really possible. I have a large DLL with a few thousand lines and 18 different CPP modules. This is a late stage in the second thread, after much network I/O and HTTP downloading (using a separate, MFC DLL).
For that reason I'd appreciate any suggestions, no matter how general, and I'll try them out.
TheSheep is offline   Reply With Quote
Old 09-16-2005, 09:51 PM   #2 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
What makes you think the allocation failed to start wiith?
__________________
Valmont is offline   Reply With Quote
Old 09-17-2005, 03:04 AM   #3 (permalink)
Locutus
Registered User
 
Join Date: Aug 2005
Posts: 20
Locutus is on a distinguished road
If I compile your code into a small program like this:
Code:
int MyNewHandler(size_t)
{
	puts("[MyNewHandler] Allocation error!");
	return 0;
}

int main()
{
	unsigned char *c;

	puts("[TryMemAlloc] Started......");

	_set_new_handler(MyNewHandler);

	try
	{
		c=new unsigned char[0x7fffffff];
	}
	catch(...)
	{
		puts("[TryMemAlloc] Exception thrown!");
	}
	if(c==0)
		puts("[TryMemAlloc] char not allocated!");
	else
		printf("[TryMemAlloc] char allocated at %p.\n",c);

	puts("[TryMemAlloc] Done");

	return EXIT_SUCCESS;
}
I get this as output (MSVC6):
Code:
[TryMemAlloc] Started......
[MyNewHandler] Allocation error!
[TryMemAlloc] char not allocated!
[TryMemAlloc] Done
Quote:
Originally Posted by TheSheep
Edit - I appreciate it's preferable to post full compilable code but it's not really possible. I have a large DLL with a few thousand lines and 18 different CPP modules. This is a late stage in the second thread, after much network I/O and HTTP downloading (using a separate, MFC DLL).
For that reason I'd appreciate any suggestions, no matter how general, and I'll try them out.
At first sight, I don't see anything obvious in your code that would prevent the handler from getting called. It is fairly rare for new to fail due to "memory exhaustion" these days, unless you've got for example a huge memory leak somewhere. It might be a good idea to have a look at how much memory your program allocates, for example by using the Windows task manager. (I assume you're running on Windows since you're using MSVC). The fact that the program is multithreaded doesn't make things easier either . In general, if you want us to be usefull, your best bet is probably to try and create the smallest possible program that fails in this way. In fact, it's quite possible that doing so leads to you finding the problem yourself .

Note that this isn't necessarily standard C++ either, since _set_new_handler is an MS specific "extension". (Arguably, doing *anything* semi-non-trivial with MSVC probably isn't standard )
Locutus is offline   Reply With Quote
Old 09-17-2005, 04:59 AM   #4 (permalink)
TheSheep
Registered User
 
TheSheep's Avatar
 
Join Date: Mar 2005
Location: UK
Posts: 11
TheSheep is on a distinguished road
Send a message via ICQ to TheSheep Send a message via AIM to TheSheep Send a message via MSN to TheSheep Send a message via Yahoo to TheSheep
@Valmont: new returned NULL.
@Locutus: like you suggested, I pulled out huge chunks of my program until it worked.

Part of my program is the Unreal API, a set of headers and libraries for making mods for Unreal-engine games. I stumbled across this:
inline void* operator new( unsigned int Size )
A little tweaking, and the output is now this:
Code:
[TryMemAlloc] Started......
"inline void* operator new (unsigned int size)" has been called.
[TryMemAlloc] char not allocated!
[TryMemAlloc] Done.
So I think I've found my problem.

Thanks for all the advice. The learning curve continues...
TheSheep is offline   Reply With Quote
Old 09-17-2005, 05:29 AM   #5 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Since this is the standard C/C++ forum, the code would be different. See comments as well for a few tips:
Code:
#include <iostream>
#include <new> //set_new_handler()
#include <cstdlib> //abort()

using namespace std;

//The standard denotes set_new_handler to be defined as:
// typedef void (*ptrF)()
void MyNewHandler()
{
  cerr<<"[MyNewHandler] Allocation error!";
  
  //std::abort()... use this as a very last resort. 
  //Solution: use the standard provided exception handling mechanism for 
  //allocation failures by calling its appropriate exception.
  abort();
}

int main()
{
  unsigned char *c;
  
  //Now we install our own handler. 
  //NOTE: if this handler is called, operator new() will NEVER retrun NULL.
  set_new_handler(MyNewHandler);

  try
  {
    c=new unsigned char[0x7fffffff];
  }
  catch(...)
  {
    //This will never be shown!
    cout <<"[TryMemAlloc] Exception thrown!";
  }
  
  cout<<" char allocated at address: " << c << endl;
  delete[] c;

  return 0;
}
The code posted by the OP is not part of the ISO standard.
__________________
Valmont is offline   Reply With Quote
Old 09-17-2005, 05:33 AM   #6 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Quote:
@Valmont: new returned NULL.
Perhaps (not on mine though!) . Best thing is to upgrade to a new compiler. See the sticky for two IDE's with new compilers in it.
__________________

Last edited by Valmont; 09-17-2005 at 06:00 AM.
Valmont is offline   Reply With Quote
Old 09-17-2005, 06:20 AM   #7 (permalink)
Valmont
[code][/code] enforcer
 
Valmont's Avatar
 
Join Date: Mar 2003
Location: Netherlands
Posts: 1,544
Valmont is on a distinguished road
Before the days of exception handling, a failure of operator new set the pointer to NULL. The pointer needed to be tested explicitly for NULL to check for failures. These days that is not needed anymore because we have a more neat way of exception handling. But setting the pointer to NULL will not occur anymore.
See how easy it can be:
Code:
#include <iostream>
#include <new> 
using namespace std;

int main()
{
  //Always healthy to initialize pointers with 0.
  unsigned char *c = 0;
  
  
  try
  {
    c=new unsigned char[0x7fffffff];
  }
  catch(const bad_alloc& xa)
  {
    cerr << "ERROR: bad allocation caught." << endl;
    //New compilers will call operator delete() if the constructor throws
    //an exception. So no worries about deletion here.
  }
  
  //Avoid sementation fault. Now it shows why initializing with 0 is handy.
  if(c!=0) //If allocated successfully...
  {
    delete[] c; //...delete pointer.
  }

  return 0;
}
__________________
Valmont is offline   Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On


Similar Threads
Thread Thread Starter Forum Replies Last Post
viewing exception of a class from jsp sde Java 9 04-28-2004 12:58 PM
Exception Handling Mjolnir Java 3 08-28-2003 08:10 PM
School District Fails Network Security sde Code Newbie News 0 07-03-2003 03:12 PM


All times are GMT -8. The time now is 09:37 AM.


Powered by vBulletin® Version 3.7.0
Copyright ©2000 - 2008, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.0.0 RC8





Copyright © 2000-2008, Milano Interactive
Web Hosting provided by Portal 360 Web Hosting