_wcsdup 内存未在 C++Builder 中释放

问题描述 投票:0回答:1

我在释放 _wcsdup 分配的内存以创建 TComboBox 的 TObject 指针时遇到问题。我认为当 TComboBox 或 Parent TForm 被释放时,该内存会自动释放。我正在使用 TComboBox 函数 AddItem() 将可见文本和指针值添加到 TComboBox。当我退出应用程序时,我的内存泄漏检测器显示 _wcsdup 分配的内存尚未释放。

我的代码如下。

int i=0;
UnicodeString Description;
UnicodeString Symbol;
wchar_t *MyPointerValue;

for(i=0; i<MyStringList1->Count; i++){
  Description = MyStringList1->Strings[i];
  Symbol      = MyStringList2->Strings[i];
  MyPointerValue = _wcsdup(Symbol.c_str());

  ComboBox1->AddItem(Description, (TObject *) MyPointerValue );
}

我尝试添加代码 if(MyPointerValue != NULL){ free(MyPointerValue);在我的 for 循环中,如下所示,但这会释放指针内存,因此不会向 TComboBox 添加任何内容。这确实解决了我的内存泄漏软件找到不可用内存的问题。

for(i=0; i<MyStringList1->Count; i++){
  Description = MyStringList1->Strings[i];
  Symbol      = MyStringList2->Strings[i];
  MyPointerValue = _wcsdup(Symbol.c_str());

  ComboBox1->AddItem(Description, (TObject *) MyPointerValue );

  if(MyPointerValue != NULL){
    free(MyPointerValue);
  }
}

我还尝试通过将以下代码添加到 FormClose 事件来直接释放 ComboBox TObject 指针内存。 调用 ->Free();产生错误。

for(i=ComboBox1->Items->Count-1; i>-1; i--){
  if( ComboBox1->Items->Objects[i] ){
    ComboBox1->Items->Objects[i]->Free();
  }
}

如何确保 _wcsdup 内存始终被释放?

请注意,我正在使用 C++Builder 12.2 Update 2 和 Win64X VCL 平台。

c++builder wcsdup
1个回答
0
投票

我无法释放

_wcsdup
分配的内存来为
TObject
创建
TComboBox
指针。

我不建议使用

_wcsdup()
来完成此任务。 使用
new
来创建和存储
UnicodeString
对象,例如:

for(int i = 0; i < MyStringList1->Count; ++i)
{
  UnicodeString Description     = MyStringList1->Strings[i];
  UnicodeString Symbol          = MyStringList2->Strings[i];
  UnicodeString *MyPointerValue = new UnicodeString(Symbol);

  ComboBox1->AddItem(Description, (TObject *) MyPointerValue );
}

我认为当

TComboBox
或父级
TForm
被释放时,该内存会自动释放。

不,内存没有被释放。使用

_wcsdup()
手动分配的内存必须使用
free()
(或
delete
new
)手动释放。

即使您将实际的基于

TObject
的对象存储到
TComboBox::Items->Objects[]
属性中,VCL 仍然不会自动释放内存。
TComboBox
根本不拥有
TObject
指针,它们是您拥有的任意数据,VCL对它们指向的内容不做任何假设。

将此与

TStringList::Objects[]
属性进行对比,通过将 TStringList::OwnsObjects 属性设置为
true
 可以自动获取所有权并释放。  但是,这仅适用于基于 
TObject

的有效对象。

我正在使用 
TComboBox
 函数 
AddItem()
 将可见文本和指针值添加到 
TComboBox
。当我退出应用程序时,我的内存泄漏检测器显示 
_wcsdup

分配的内存尚未释放。

这是正确的,因为您没有释放手动分配的内存。

我尝试在如下所示的 
if(MyPointerValue != NULL){ free(MyPointerValue); }
 循环中添加代码 
for
 ,但这会释放指针内存,因此不会向 
TComboBox

添加任何内容。这确实解决了我的内存泄漏软件找到不可用内存的问题。

这正是您需要做的。 然而,你在“错误”的地方做这件事。 不要在填充 for

TComboBox
 循环中执行 in 操作。  在使用完 
TComboBox 项目后执行此操作,例如在程序关闭期间,或者使用新项目重新填充
TComboBox
时。

我还尝试通过将以下代码添加到
TObject

事件来直接释放 ComboBox

FormClose
指针内存。对
->Free();
的调用会生成错误。

这是正确的方法,但是您必须使用
free()

而不是

TObject::Free()
,因为您没有存储基于
TObject
的有效对象,这就是
Free()
崩溃的原因。
尝试更像这样的事情:

void __fastcall TMyForm::FormClose(TObjct* Sender, TCloseAction &Action) { ClearComboBox(); } void __fastcall TMyForm::PopulateComboBox() { ClearComboBox(); for(int i = 0; i < MyStringList1->Count; ++i) { UnicodeString Description = MyStringList1->Strings[i]; UnicodeString Symbol = MyStringList2->Strings[i]; wchar_t *MyPointerValue = _wcsdup(Symbol.c_str()); // or: UnicodeString *MyPointerValue = new UnicodeString(Symbol); ComboBox1->AddItem(Description, (TObject *) MyPointerValue ); } } void __fastcall TMyForm::ClearComboBox() { for(int i = ComboBox1->Items->Count-1; i > -1; --i) { free( (wchar_t*) ComboBox1->Items->Objects[i]) ); // or: delete (UnicodeString*) ComboBox1->Items->Objects[i]); } ComboBox1->Clear(); }

现在,话虽这么说,如果您的 
MyStringList1

MyStringList2
列表在填充
TComboBox
时保持有效,那么更简单的解决方案是将
indexes
存储在 Objects[] 属性中,而不是实际的
strings
。 这样,您就不必担心释放TComboBox中的内存,例如:
void __fastcall TMyForm::PopulateComboBox()
{
  ComboBox1->Clear();

  for(int i = 0; i < MyStringList1->Count; ++i)
  {
    UnicodeString Description = MyStringList1->Strings[i];
    UnicodeString Symbol      = MyStringList2->Strings[i];

    ComboBox1->AddItem(Description, (TObject *) (IntPtr) i );
  }
}

然后您可以在需要时检索 
Symbol

字符串:

int index = (int) (IntPtr) ComboBox1->Items->Objects[...];
UnicodeString Symbol = MyStringList2->Strings[index];
...

	
最新问题
© www.soinside.com 2019 - 2025. All rights reserved.