找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4776|回复: 6

ACE_Data_Block的内存泄漏,请大家指教!

[复制链接]
发表于 2007-12-21 21:54:36 | 显示全部楼层 |阅读模式
看了ACE5.5的ACE_Message_Block和ACE_Data_Block代码,觉得有内存泄漏问题。
对下面的ACE_Message_Block构函,如果data为0(null),ACE_Message_Block
的flags_标志为0(故ACE_Data_Block的引用计数为0时将调用ACE_Data_Block的析构函数);
ACE_Data_Block标志为ACE_Message_Block::DONT_DELETE;
在ACE_Data_Block的构函中会调用ACE_ALLOCATOR (this->base_,
                   (char *) this->allocator_strategy_->malloc (size)); 为base_分配内存
                  
但在ACE_Data_Block的析构函数中,由于ACE_Data_Block标志为ACE_Message_Block::DONT_DELETE,
故不会释放base_的内存!
                  
   相关代码如下:               
  1. ACE_Message_Block::ACE_Message_Block (const char *data,
  2.                                       size_t size,
  3.                                       unsigned long priority)
  4.   : flags_ (0),
  5.     data_block_ (0)
  6. {
  7.   ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
  8.   if (this->init_i (size,    // size
  9.                     MB_DATA, // type
  10.                     0,       // cont
  11.                     data,    // data  =null
  12.                     0,       // allocator
  13.                     0,       // locking strategy
  14.                     ACE_Message_Block::DONT_DELETE, // flags   
  15.                     priority, // priority
  16.                     ACE_Time_Value::zero,     // execution time
  17.                     ACE_Time_Value::max_time, // absolute time of deadline
  18.                     0,  // data block
  19.                     0,  // data_block allocator
  20.                     0) == -1) // message_block allocator
  21.     ACE_ERROR ((LM_ERROR,
  22.                 ACE_LIB_TEXT ("ACE_Message_Block")));
  23. }
  24. ACE_Message_Block::init_i (size_t size,
  25.                            ACE_Message_Type msg_type,
  26.                            ACE_Message_Block *msg_cont,
  27.                            const char *msg_data,
  28.                            ACE_Allocator *allocator_strategy,
  29.                            ACE_Lock *locking_strategy,
  30.                            Message_Flags flags,
  31.                            unsigned long priority,
  32.                            const ACE_Time_Value &execution_time,
  33.                            const ACE_Time_Value &deadline_time,
  34.                            ACE_Data_Block *db,
  35.                            ACE_Allocator *data_block_allocator,
  36.                            ACE_Allocator *message_block_allocator)
  37. {
  38.   //...... 略去无关代码
  39.   
  40.   if (this->data_block_ != 0)
  41.     {
  42.       this->data_block_->release ();
  43.       this->data_block_ = 0;
  44.     }
  45.   if (db == 0)
  46.     {
  47.       if (data_block_allocator == 0)
  48.         ACE_ALLOCATOR_RETURN (data_block_allocator,
  49.                               ACE_Allocator::instance (),
  50.                               -1);
  51.       ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC);
  52.       
  53.       ACE_NEW_MALLOC_RETURN (db,
  54.                              static_cast<ACE_Data_Block *> (
  55.                                data_block_allocator->malloc (sizeof (ACE_Data_Block))),
  56.                              ACE_Data_Block (size,
  57.                                              msg_type,  
  58.                                              msg_data,  // =null
  59.                                              allocator_strategy,
  60.                                              locking_strategy,
  61.                                              flags, // =ACE_Message_Block::DONT_DELETE
  62.                                              data_block_allocator),
  63.                              -1);
  64.       ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR);
  65.     }
  66.   // Reset the data_block_ pointer.
  67.   this->data_block (db);
  68.   // If the data alloc failed, the ACE_Data_Block ctor can't relay
  69.   // that directly. Therefore, need to check it explicitly.
  70.   if (db->size () < size)
  71.     return -1;
  72.   return 0;
  73. }
  74. ACE_Data_Block::ACE_Data_Block (size_t size,
  75.                                 ACE_Message_Block::ACE_Message_Type msg_type,
  76.                                 const char *msg_data,
  77.                                 ACE_Allocator *allocator_strategy,
  78.                                 ACE_Lock *locking_strategy,
  79.                                 ACE_Message_Block::Message_Flags flags,
  80.                                 ACE_Allocator *data_block_allocator)
  81.   : type_ (msg_type),
  82.     cur_size_ (0),          // Reset later if memory alloc'd ok
  83.     max_size_ (0),
  84.     flags_ (flags), // =ACE_Message_Block::DONT_DELETE
  85.     base_ (const_cast <char *> (msg_data)), //base = 0
  86.     allocator_strategy_ (allocator_strategy),
  87.     locking_strategy_ (locking_strategy),
  88.     reference_count_ (1),
  89.     data_block_allocator_ (data_block_allocator)
  90. {
  91.   ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
  92.   ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR2_ENTER);
  93.   // If the user didn't pass one in, let's use the
  94.   // <ACE_Allocator::instance>.
  95.   if (this->allocator_strategy_ == 0)
  96.     ACE_ALLOCATOR (this->allocator_strategy_,
  97.                    ACE_Allocator::instance ());
  98.   if (this->data_block_allocator_ == 0)
  99.     ACE_ALLOCATOR (this->data_block_allocator_,
  100.                    ACE_Allocator::instance ());
  101.   if (msg_data == 0)  // msg_data = 0,为base_分配内存
  102.     ACE_ALLOCATOR (this->base_,
  103.                    (char *) this->allocator_strategy_->malloc (size));
  104.     // ACE_ALLOCATOR returns on alloc failure...
  105.   // The memory is legit, whether passed in or allocated, so set the size.
  106.   this->cur_size_ = this->max_size_ = size;
  107. }
  108. ACE_Data_Block::~ACE_Data_Block (void)
  109. {
  110.   // Sanity check...
  111.   ACE_ASSERT (this->reference_count_ <= 1);
  112.   // Just to be safe...
  113.   this->reference_count_ = 0;
  114.   if (ACE_BIT_DISABLED (this->flags_,
  115.                         ACE_Message_Block::DONT_DELETE))     //this->flags_=ACE_Message_Block::DONT_DELETE
  116.     {
  117.       this->allocator_strategy_->free ((void *) this->base_); //不会执行该语句,base_指向的内存没有释放,泄漏!
  118.       this->base_ = 0;
  119.     }
  120. }
复制代码
 楼主| 发表于 2007-12-21 21:54:47 | 显示全部楼层
ACE_Message_Block的数据直接指向了参数中const char *data这块内存,这块内存不是由ACE_Message_Block创建的,所以不必释放。
 楼主| 发表于 2007-12-21 21:54:57 | 显示全部楼层
不同意楼上的。是base_的内存泄漏,不是data。

在ACE_Data_Block的构函中有如下语句:

if (msg_data == 0)  // 此时 msg_data = 0,为base_分配内存
    ACE_ALLOCATOR (this->base_,
                   (char *) this->allocator_strategy_->malloc (size));
    // ACE_ALLOCATOR returns on alloc failure...

但在ACE_Data_Block的析构函数中,由于ACE_Data_Block标志为ACE_Message_Block::DONT_DELETE,
故不会释放base_的内存!
 楼主| 发表于 2007-12-21 21:55:02 | 显示全部楼层
base_就是指向的data

ACE_Data_Block::ACE_Data_Block (size_t size,
                                ACE_Message_Block::ACE_Message_Type msg_type,
                                const char *msg_data,
                                ACE_Allocator *allocator_strategy,
                                ACE_Lock *locking_strategy,
                                ACE_Message_Block::Message_Flags flags,
                                ACE_Allocator *data_block_allocator)
  : type_ (msg_type),
    cur_size_ (0),          // Reset later if memory alloc'd ok
    max_size_ (0),
    flags_ (flags), // =ACE_Message_Block::DONT_DELETE
    base_ (const_cast <char *> (msg_data)), //base = 0
    allocator_strategy_ (allocator_strategy),
    locking_strategy_ (locking_strategy),
    reference_count_ (1),
    data_block_allocator_ (data_block_allocator)
 楼主| 发表于 2007-12-21 21:55:09 | 显示全部楼层
在ACE_Data_Block的构函初始化列表中base_就是指向的data

//(base_ (const_cast <char *> (msg_data)), )
但在构造函数体中有下列语句

if (msg_data == 0)  // msg_data = 0,为base_分配内存
    ACE_ALLOCATOR (this->base_,
                   (char *) this->allocator_strategy_->malloc (size));
这样如果data为空(也就是msg_data 为空),会重新为base_分配内存,此时base_和data

已经不一样了。
 楼主| 发表于 2007-12-21 21:55:17 | 显示全部楼层
ACE_Message_Block::ACE_Message_Block (const char *data,
                                      size_t size,
                                      unsigned long priority)
data为空的话,size也应该为0啊, malloc(0)没事
 楼主| 发表于 2007-12-21 21:55:22 | 显示全部楼层
如果是这样,就不会有问题了!但客户要遵守该约定:data为空,size也应该为0
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-23 15:22 , Processed in 0.021192 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表