On 2011-07-14 01:11, Loopback wrote:
Hello!
I've been working on a project where I had to do all memory handling
explicitly because no destructors were called. When I got too tired
of the explicit memory handling I decided to trace what was causing
this error. After hours of code stripping I had gotten myself a
small concrete sample which could demonstrate the error.
Now to the point; I create a program using WinMain as entry point. The
program template i use, is identical to the win32 template on the
D-Website. If you have used this template you know that all user code
goes within the function "myWinMain". In this function I declare a class
named Foo. When I create this class an empty constructor is called, and
then the function "myWinMain" returns.
Now the program calls Runtime.terminate, which is supposed to take
care of the memory garbage and etc. This does not work. The terminate
function call throws an Error, "Memory Allocation Failure".
This failure originates in the 'Foo' destructor, which in turn creates
a appender object of type string. My question is; how come this throws
an error?
Not to forget the important part:
// Import WINAPI
import win32.windows;
// Core API
import core.runtime;
// For appender
import std.range;
extern (Windows) int WinMain(HINSTANCE hInstance, HINSTANCE
hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
int result;
void exceptionHandler(Throwable e) { throw e; }
try
{
Runtime.initialize(&exceptionHandler);
result = myWinMain(hInstance, hPrevInstance, lpCmdLine,
nCmdShow);
Runtime.terminate(&exceptionHandler);
}
// If you use "Exception" object instead here, the program fails
// silently without any MessageBox of any kind. The program, in this
case quits
// automatically after about 7-12 seconds, without any destructors
called.
// If you instead use Error object to catch the error, a message pops
// up saying, "Memory Allocation Failure", why?
catch (/*Exception*/Error o) // catch any uncaught exceptions
{
MessageBoxA(null, cast(char *) o.toString(), "Error", MB_OK |
MB_ICONEXCLAMATION);
result = 0;// failed
}
return result;
}
int myWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR
lpCmdLine, int nCmdShow)
{
Foo foo = new Foo;
return (foo !is null);
}
class Foo
{
public:
this()
{
}
~this()
{
// This line causes memory allocation failure
auto writer = appender!string();
}
}