Opened 19 years ago

Last modified 19 years ago

#810 closed defect (invalid)

Memory Leaks when delete GDALDriver Object

Reported by: christophe.sandri@… Owned by: warmerdam
Priority: high Milestone:
Component: GDAL_Raster Version: unspecified
Severity: major Keywords:
Cc:

Description

[VC++ 6.0][Windows 2000]
I created my own dataset with its driver (ex: MyDataset)
MyDataset is ok.

I made the register function as shown in the tutorial jdemdataset.cpp
void GDALRegister_MyDriver()
{
   GDALDriver *poDriver;
   if(GDALGetDriverByName("MyFormat") == NULL)
   {
    ...
   }
}

I don't add my driver to GDAL Tree

In my main function I wrote

void main ()
{
   GDALRegister_MyDriver();
   ...
   GDALDestroyDriverManager();  /* Bug ? */
}
In debug mode I trace the execution
If I don't use the GDALDestroyDriverManager, there is no error but a 
MemoryLeaks because the GDALDriver Object is not released.
If I use this function, I have an error when the function deletes the driver 
object. 
(extract: gdaldrivermanager.cpp)
GDALDriverManager::~GDALDriverManager()

{
/* -------------------------------------------------------------------- */
/*      Destroy the existing drivers.                                   */
/* -------------------------------------------------------------------- */
    while( GetDriverCount() > 0 )
    {
        GDALDriver      *poDriver = GetDriver(0);

        DeregisterDriver(poDriver);
        delete poDriver;
    }
    ...

delete poDriver occurs an error: HEAP[TestGDAL.exe]: Invalid Address specified 
to RtlFreeHeap( 370000, 972968 )

I made another test

#include "gdal_priv.h"
void main()
{
   GDALDriver *poDriver = new GDALDriver();
   if(poDriver)
      delete poDriver;
}

I have the same error on delete poDriver

Could you help me to resolve this problem ?

Thanks.
---------------------------
Christophe Sandri.

Change History (2)

comment:1 by warmerdam, 19 years ago

Christophe, 

I tried your last example and this worked fine for me when I compiled either
with /MD or without it.   

Your earlier problem sound typical of an application with multiple heaps and
confusion about which heap objects are in when they are deleted.  If you don't
compile everything with /MD the it is likely that different DLLs will have their
own heaps.  Notably your main .exe where you "new" your own driver, and 
GDAL12.DLL where the driver will end up being deleted will have their own heaps.
Because the delete operation is done in the DLL the delete operator tries to 
free the memory into the GDAL12.DLL heap, but it was actually created on the
main .exe's heap.  So disaster occurs - heap corruption or a runtime check
detects it in advance. 

It is hard for me to know exactly whether the above is the problem or not
since you haven't provided details of VC++ switches you built with. 

The simple solution is to ensure that you build GDAL and your main application
with /MD - which uses MSVCRT.DLL run time C library to provide one global heap.

If this isn't the problem then you will have to provide more details.  But
this would appear to be a windows specific build problem and not really a 
problem in GDAL itself.  There is a limited amount of time I can spend helping
folks with non-GDAL windows compiler/build/environment issues. 

If you detect a specific bug in GDAL itself, feel free to re-open this bug
report.  

  

comment:2 by christophe.sandri@…, 19 years ago

Thanks Frank,

I tried the /MD parameter and it seems to run correctly now.

For more informations, I used another way to solve that problem
I wrote an herited class from GDALDriver

class MyDriver : public GDALDriver
{  // An empty class
};

In the register function, ...

void GDALRegister_MyDriver(void)
{
   GDALDriver *poDriver;
   if(GDALGetDriverByName("MyFormat") == NULL)
   {
       poDriver = new MyDriver();
       ...
   }

}

When the GDALDestroyDriverManager function is called, there is no more
Invalid Address specified.

My way seems to work but I prefer your solution that looks like cleaner.

Thanks
Note: See TracTickets for help on using tickets.