ACE_Data_Block的内存泄漏,请大家指教!
看了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_的内存!
相关代码如下:
ACE_Message_Block::ACE_Message_Block (const char *data,
size_t size,
unsigned long priority)
: flags_ (0),
data_block_ (0)
{
ACE_TRACE ("ACE_Message_Block::ACE_Message_Block");
if (this->init_i (size, // size
MB_DATA, // type
0, // cont
data, // data=null
0, // allocator
0, // locking strategy
ACE_Message_Block::DONT_DELETE, // flags
priority, // priority
ACE_Time_Value::zero, // execution time
ACE_Time_Value::max_time, // absolute time of deadline
0,// data block
0,// data_block allocator
0) == -1) // message_block allocator
ACE_ERROR ((LM_ERROR,
ACE_LIB_TEXT ("ACE_Message_Block")));
}
ACE_Message_Block::init_i (size_t size,
ACE_Message_Type msg_type,
ACE_Message_Block *msg_cont,
const char *msg_data,
ACE_Allocator *allocator_strategy,
ACE_Lock *locking_strategy,
Message_Flags flags,
unsigned long priority,
const ACE_Time_Value &execution_time,
const ACE_Time_Value &deadline_time,
ACE_Data_Block *db,
ACE_Allocator *data_block_allocator,
ACE_Allocator *message_block_allocator)
{
//...... 略去无关代码
if (this->data_block_ != 0)
{
this->data_block_->release ();
this->data_block_ = 0;
}
if (db == 0)
{
if (data_block_allocator == 0)
ACE_ALLOCATOR_RETURN (data_block_allocator,
ACE_Allocator::instance (),
-1);
ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_ALLOC);
ACE_NEW_MALLOC_RETURN (db,
static_cast<ACE_Data_Block *> (
data_block_allocator->malloc (sizeof (ACE_Data_Block))),
ACE_Data_Block (size,
msg_type,
msg_data,// =null
allocator_strategy,
locking_strategy,
flags, // =ACE_Message_Block::DONT_DELETE
data_block_allocator),
-1);
ACE_TIMEPROBE (ACE_MESSAGE_BLOCK_INIT_I_DB_CTOR);
}
// Reset the data_block_ pointer.
this->data_block (db);
// If the data alloc failed, the ACE_Data_Block ctor can't relay
// that directly. Therefore, need to check it explicitly.
if (db->size () < size)
return -1;
return 0;
}
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)
{
ACE_TRACE ("ACE_Data_Block::ACE_Data_Block");
ACE_FUNCTION_TIMEPROBE (ACE_DATA_BLOCK_CTOR2_ENTER);
// If the user didn't pass one in, let's use the
// <ACE_Allocator::instance>.
if (this->allocator_strategy_ == 0)
ACE_ALLOCATOR (this->allocator_strategy_,
ACE_Allocator::instance ());
if (this->data_block_allocator_ == 0)
ACE_ALLOCATOR (this->data_block_allocator_,
ACE_Allocator::instance ());
if (msg_data == 0)// msg_data = 0,为base_分配内存
ACE_ALLOCATOR (this->base_,
(char *) this->allocator_strategy_->malloc (size));
// ACE_ALLOCATOR returns on alloc failure...
// The memory is legit, whether passed in or allocated, so set the size.
this->cur_size_ = this->max_size_ = size;
}
ACE_Data_Block::~ACE_Data_Block (void)
{
// Sanity check...
ACE_ASSERT (this->reference_count_ <= 1);
// Just to be safe...
this->reference_count_ = 0;
if (ACE_BIT_DISABLED (this->flags_,
ACE_Message_Block::DONT_DELETE)) //this->flags_=ACE_Message_Block::DONT_DELETE
{
this->allocator_strategy_->free ((void *) this->base_); //不会执行该语句,base_指向的内存没有释放,泄漏!
this->base_ = 0;
}
}
ACE_Message_Block的数据直接指向了参数中const char *data这块内存,这块内存不是由ACE_Message_Block创建的,所以不必释放。 不同意楼上的。是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_的内存! 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) 在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
已经不一样了。 ACE_Message_Block::ACE_Message_Block (const char *data,
size_t size,
unsigned long priority)
data为空的话,size也应该为0啊, malloc(0)没事 如果是这样,就不会有问题了!但客户要遵守该约定:data为空,size也应该为0
页:
[1]