0

给出以下函数:

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

为什么编译器会为第一个示例生成析构函数调用

4

2 回答 2

1

Allocator myAllocator = shm.allocator();是复制初始化,涉及转换构造函数(来自 a osal_allocator*)和复制构造函数(来自临时Allocator)的调用。被调用的析构函数是临时Allocator对象的析构函数。

崩溃可能是由于缺少复制构造函数,或者Allocator.

您声称将初始化更改为

Allocator myAllocator( shm.allocator );

有效 - 这是因为不涉及复制 - 直接调用转换构造函数,不创建临时对象。

阅读“三法则”。

基本上,如果一个类需要析构函数、复制构造函数或复制赋值运算符(通常是类管理资源的情况),则它需要所有这三个

于 2012-12-20T11:54:49.060 回答
1

有了这条线

Allocator myAllocator = shm.allocator();

您正在执行以下操作:

  1. 构造一个新的Allocator临时对象
  2. Allocator调用rhs 是临时的复制构造函数
  3. 销毁点1创建的临时对象

有两种可能的操作是您不考虑的并且可能会导致 SIG SEV:复制构造函数和析构函数。

于 2012-12-20T12:00:12.360 回答