提供以下功能:
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 :(得分:1)
Allocator myAllocator = shm.allocator();
是复制初始化,涉及转换构造函数(来自osal_allocator*
)和复制构造函数(来自临时Allocator
)的调用。被调用的析构函数是临时Allocator
对象的析构函数。
崩溃可能是由于Allocator
中缺少复制构造函数或执行不当的复制构造函数。
这可以通过将初始化更改为
的说法来支持Allocator myAllocator( shm.allocator );
有效 - 这是因为没有涉及复制 - 直接调用转换构造函数,不创建临时对象。
Read up on "the rule of three".
基本上,如果一个类需要析构函数,复制构造函数或复制赋值运算符(通常是类管理资源时的情况),则需要所有这三个。
答案 1 :(得分:1)
使用此行
Allocator myAllocator = shm.allocator();
您正在执行以下操作:
Allocator
临时对象Allocator
的复制构造函数,其中rhs是临时的您可能会考虑两种可能的操作,这可能导致SIG SEV:复制构造函数和析构函数。