2

I'm new to C++ and a bit confused regarding auto_ptr.

I have a class which inside has a static auto_ptr.

static std::auto_ptr<MyCompany::CConnection> con = std::auto_ptr<MyCompany::CConnection> (util::getDBConnection() );

Util::getDBConnection() implementation :

CConnection* util::getDBConnection(){
        try
        {   
            cout<< &MyCompany::GetFermatConnection();                   
            return  &MyCompany::GetFermatConnection();            
        }
        catch(...)
        {   
            //connect to local DB
            throw;
        }
    }     

However when my program finished, it always hit an exception in memory, during the destructor of auto pointer.

~auto_ptr()
    {   // destroy the object
    if (_Myptr != 0)
        delete _Myptr; // exception in this line.
    }

The exception is "Unhandled exception at 0x00000001800024e8 in TestDLL.exe: 0xC0000005: Access violation reading location 0xffffffffffffffff."

I understand that auto_ptr will try release any memory when it reach the end of its scope. But, in this case I don't have any idea what goes wrong. Does anyone know what is the possible cause?

Rudy
  • 7,008
  • 12
  • 50
  • 85
  • Is the `auto_ptr` initialized correctly? Can you put a break point in the `util::getDBConnection()` and see what it returns? – Naveen Mar 05 '12 at 07:02
  • Does `util::getDBConnection()` returns -1 by anychance ? – J.N. Mar 05 '12 at 07:03
  • Breakpoint shows that util.getDBConnection returns 0000000002899A20. – Rudy Mar 05 '12 at 07:11
  • It seems to me that using a static `auto_ptr` is probably not what you want, as it does not really offer any lifetime management at all. It will only get destroyed at the very end of the program, a case for which you don't need an `auto_ptr` in the first place. The only place where this could be useful is when using custom deleters but that does not seem to be the case here. – ComicSansMS Mar 05 '12 at 07:50
  • 1
    From the implementation of `getDBConnection` it looks the memory for `DBConnection` is not allocated using `new`. – Naveen Mar 05 '12 at 07:55

2 Answers2

2

I don't know the specifics of your code, but I would guess that there is code that sets pointers to -1 when deleting them, and that the crash is from a double-delete on the same pointer.

COM and auto_ptr probably shouldn't be mixed, which is what it appears is happening given the COM:: portion of the code.

auto_ptr is more of a 'strong pointer' - It owns it and deletes it unless it's ripped away.

COM uses a ref counted model. Objects are created with reference count 1. Any new reference should be AddRef'd and when no longer needed, Release().

Look at a COM specific smart pointer like this instead.

Apologies if I am incorrectly guessing about the COM scenario.

Joe
  • 2,946
  • 18
  • 17
  • sorry. COM = Company_name. I have a policy to mask my company name before posting. I have updated my question to remove any confusion – Rudy Mar 05 '12 at 07:05
  • No worries. Assuming the code uses the pointer successfully, I'm still going to bet on double-delete/free, but with much less certainty on where. Add a breakpoint to the destructor of CConnection if possible - hopefully there are not many instances of that type and it will help track down the problem. – Joe Mar 05 '12 at 18:40
2

Although you've shown the implementation of util::getDBConnection, it doesn't really answer the question, which is whether what it returns is ultimately a pointer that was allocated with new.

If it was, then an error message when you attempt to delete that pointer indicates that your heap has probably gotten corrupted (quite possibly in some completely unrelated code).

If it's returning something that wasn't allocated with new, then the problem is even simpler -- since auto_ptr uses delete on the pointer, it can only be used with something that was allocated with new. Using it on a pointer that was allocated any other way will give UB.

Jerry Coffin
  • 476,176
  • 80
  • 629
  • 1,111