Дайте следующую функцию:
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
Почему компилятор генерирует вызов деструктора для первого примера
С этой линией
Allocator myAllocator = shm.allocator();
Вы делаете следующие операции:
Allocator
временный объектAllocator
где RHS является временнымЕсть две возможные операции, которые вы не рассматриваете, и которые могут вызвать SIG SEV: конструктор копирования и деструктор.
Allocator myAllocator = shm.allocator();
инициализация копии и включает в себя вызов конструктора преобразования (из osal_allocator*
) и конструктор копирования (из временного Allocator
). Деструктор, который вызывается, это временный Allocator
объект.
Сбой, вероятно, из-за отсутствующего конструктора копирования или плохо реализованного конструктора копирования в Allocator
,
Это подтверждается вашим утверждением, что изменение инициализации на
Allocator myAllocator( shm.allocator );
работает — это потому, что здесь нет никакой копии — конструктор преобразования вызывается напрямую, временный объект не создается.
По сути, если класс требует деструктора, конструктора копирования или оператора присваивания копии (что обычно имеет место, когда класс управляет ресурсами), он требует все трое.