Почему деструктор сразу после вызова неявного конструктора преобразования типов?

Дайте следующую функцию:

osal_allocator* SharedMemoryManager::allocator();I

куда osal_allocator является структурой ‘c’, содержащей указатели на функции.

И класс-обертка, который предоставляет следующий конструктор:

Allocator::Allocator( osal_allocator* );

Функция выполняет следующий вызов:

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

Код не работает с SIG SEGV, Причина в том, что на линии 003 деструктор для myAllocator вызывается сразу после вызова его конструктора. Это означает, что myAllocator недействителен на линии 005, так как он был разрушен.

(Примечание: конструктор по умолчанию не вызывается, равно как и операторы присваивания).

Если линия 003 изменено на:

003    Allocator myAllocator( shm.allocator );

Функция работает как положено, с myAllocatorsДеструктор не вызывается, пока не выйдет за рамки.

К сожалению, я не смог воспроизвести эту проблему на простом примере.

Я использую :

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

Со следующими опциями:

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

Почему компилятор генерирует вызов деструктора для первого примера

0

Решение

С этой линией

Allocator myAllocator = shm.allocator();

Вы делаете следующие операции:

  1. Построить новый Allocator временный объект
  2. Вызовите конструктор копирования Allocator где RHS является временным
  3. Уничтожить временный объект, созданный в точке 1

Есть две возможные операции, которые вы не рассматриваете, и которые могут вызвать SIG SEV: конструктор копирования и деструктор.

1

Другие решения

Allocator myAllocator = shm.allocator(); инициализация копии и включает в себя вызов конструктора преобразования (из osal_allocator*) и конструктор копирования (из временного Allocator). Деструктор, который вызывается, это временный Allocator объект.

Сбой, вероятно, из-за отсутствующего конструктора копирования или плохо реализованного конструктора копирования в Allocator,

Это подтверждается вашим утверждением, что изменение инициализации на

Allocator myAllocator( shm.allocator );

работает — это потому, что здесь нет никакой копии — конструктор преобразования вызывается напрямую, временный объект не создается.

Читайте о «правиле трех».

По сути, если класс требует деструктора, конструктора копирования или оператора присваивания копии (что обычно имеет место, когда класс управляет ресурсами), он требует все трое.

1

По вопросам рекламы [email protected]