0

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

mark
  • 7,381
  • 5
  • 36
  • 61
  • The answer to your problems is, You need to properly & correctly follow the **Rule of Three**. – Alok Save Dec 20 '12 at 11:55
  • Please post the *actual, minimal complete code* and not just some approximation. Your code won’t compile. – Konrad Rudolph Dec 20 '12 at 11:56
  • "Why is the compiler generating invalid code for the first example" chances are areally high, that it isn't. – PlasmaHH Dec 20 '12 at 11:57
  • Your right - I instinctively followed the "rule of 3" in my attempt to reproduce the error - unfortunately the code I was calling doesn't... – mark Dec 20 '12 at 12:08

2 Answers2

1

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.

Community
  • 1
  • 1
Luchian Grigore
  • 253,575
  • 64
  • 457
  • 625
  • Ruke of Three - That is why my attempt to reproduce the issue works and the real code doesn't - it follows the rule of 3 but the code (not mine) for Allocator is missing a copy constructor.... – mark Dec 20 '12 at 12:05
1

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.

Vincenzo Pii
  • 18,961
  • 8
  • 39
  • 49