简体   繁体   中英

Why is a destructor directly after calling an implicit type conversion constructor?

Give the following function:

osal_allocator* SharedMemoryManager::allocator();I  

Where osal_allocator is a 'c' structure, containing function pointers.

And the a wrapper class that provides the following constructor:

Allocator::Allocator( osal_allocator* );

A function makes the following call:

001 SomeFunc( SharedMemoryManager* shm )
002 {
003    Allocator myAllocator = shm.allocator();
004
005    myAllocator.doSomething();
006
007    // stuff
008 }

The code fails with a SIG SEGV . The reason is that on line 003 the destructor for myAllocator is called immediately after its constructor is called. This means that myAllocator is invalid on line 005 , since it has been destroyed.

(Note: the default constructor is not being called and neither are any assignment operators).

If line 003 is changed to:

003    Allocator myAllocator( shm.allocator );

The function works as expected, with myAllocators 's destructor not being called until it goes out of scope.

Unfortunately I have not been able to reproduce this issue with a simple example.

I am using :

g++ (GCC) 4.4.6 20110731 (Red Hat 4.4.6-3)

With the following options:

c++ -MD -D__LINUX__  -g -ansi -Wall -Wextra -Wformat -Wno-format-security -Woverloaded-virtual -Iinc

Why is the compiler generating a destructor call for the first example

Allocator myAllocator = shm.allocator(); is copy initialization and involves the call of a conversion constructor (from a osal_allocator* ) and a copy constructor (from the temporary Allocator ). The destructor that's being called is that of the temporary Allocator object.

The crash is probably due to a missing copy constructor, or poorly implemented copy constructor in Allocator .

This is backed up by your claim that changing the initialization to

Allocator myAllocator( shm.allocator );

works - this is because there's no copy involved - the conversion constructor is called directly, no temporary object is created.

Read up on "the rule of three".

Basically, if a class requires either of a destructor, copy constructor or copy assignment operator (which is usually the case when a class manages resources), it requires all three of them .

With this line

Allocator myAllocator = shm.allocator();

You are doing the following operations:

  1. Construct a new Allocator temporary object
  2. Call the copy constructor of Allocator where the rhs is the temporary
  3. Destroy the temporary object created at point 1

There are two possible operations which you din't consider and that may cause the SIG SEV: copy constructor and destructor.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM