发现 BCB6 的 WideString 存在严重 bug!!!

std::coding::peasant 2008-05-21 10:01:25
现象:

WideString ws;
ws = L"";
wchar_t c[] = L"";
ws = c;


类似以上代码,只要有用 wchar_t 指针给 WideString 赋值,程序就出现错误,甚至崩溃!

原因是 WideString 的等于操作符有问题。

类的定义在 "c:\Program Files\Borland\CBuilder6\Source\vcl\wstring.h" 这个文件里面

其中等于操作符的定义:
WideString& __fastcall operator = (BSTR rhs);


实现在这个文件里面:
"c:\Program Files\Borland\CBuilder6\Source\vcl\wstring.cpp"

WideString& __fastcall WideString::operator=(BSTR src)
{
Empty();
Data = src;
return *this;
}


Empty() 函数是这样写的:

void __fastcall WideString::Empty()
{
if (Data)
{
::SysFreeString(Data);
Data = 0;
}
}


类的私有成员 Data 是这样定义的:

wchar_t *Data;


当用 whcar_t 指针给 WideString 类赋值的时候,WideString 直接保留 wchar_t 指针,而不是分配一块内存再复制内容,这样在释放内存的时候,还是直接释放 Data 指针,也就是赋值之前的那个 wchar_t 指针被释放了,释放了别人的内存,而不是类自己分配的内存,这样就引起了系统崩溃。

由于 WideString 类用的 SysFreeString 这个 API 函数释放内存,而不是用的 new 和 delete,BCB 的 CodeGuard 也无法检测内存泄漏。

不知道有没有遇到这个情况的,最近在写多语言程序,总是在 WideString 上出错,看了 VCL 源码才发现这个 bug, 郁闷。
...全文
522 38 打赏 收藏 转发到动态 举报
写回复
用AI写文章
38 条回复
切换为时间正序
请发表友善的回复…
发表回复
sanyou98 2008-06-11
  • 打赏
  • 举报
回复
关注
  • 打赏
  • 举报
回复
[Quote=引用 36 楼 sczyq 的回复:]
WideString ws = "Hello";


我都是这样写的, 不加 L


使用 wchar_t * 时,再使用 ws.b_str()
[/Quote]

不加 L 就失去 UNICODE 的意义了,换个语言的操作系统再运行就乱码了。用 WideString 的目的就是要用 UNICODE
sfengnet 2008-06-10
  • 打赏
  • 举报
回复
接分
sczyq 2008-06-10
  • 打赏
  • 举报
回复
WideString ws = "Hello";


我都是这样写的, 不加 L


使用 wchar_t * 时,再使用 ws.b_str()
BCBPLC 2008-06-09
  • 打赏
  • 举报
回复
void __fastcall TForm1::Button1Click(TObject *Sender)
{
wchar_t *w=L"Hello";
WideString ws=w;
ShowMessage(ws); // 不出错
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
WideString ws;
wchar_t *w=L"Hello";
ws=w;
ShowMessage(ws); // 出错
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{

WideString ws=L"Hello";
ShowMessage(ws); // 不出错

}
BCBPLC 2008-06-09
  • 打赏
  • 举报
回复
void __fastcall TForm1::Button1Click(TObject *Sender)
{
wchar_t *w=L"Hello";
WideString ws=w;
ShowMessage(ws); // 不出错
}
//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)
{
WideString ws;
wchar_t *w=L"Hello";
ws=w;
ShowMessage(ws); // 出错
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{

WideString ws=L"Hello";
ShowMessage(ws); // 不出错

}
  • 打赏
  • 举报
回复
我的 Active Server Object 才叫郁闷呢,写太多了,还没法调试,总出浏览网页的时候服务器坏掉的情况,这个 WideString 太难发现问题了
tangx100 2008-05-27
  • 打赏
  • 举报
回复
真是细心的人,我这还没遇到 谢谢提醒
jacknes009 2008-05-24
  • 打赏
  • 举报
回复
我没有碰到过,去看看。。。
i_love_pc 2008-05-24
  • 打赏
  • 举报
回复
关注!
lxz19880204 2008-05-23
  • 打赏
  • 举报
回复
楼主细心
遇到过类似问题,不过没考虑过是编译器问题......
Behard 2008-05-23
  • 打赏
  • 举报
回复
没有用过 widestring 学习
jone7319 2008-05-23
  • 打赏
  • 举报
回复
楼主的精神值得学习!
  • 打赏
  • 举报
回复
你没安装BCB6的更新吧,about中显示红字confidential的那是内部开发版本。:)
总共有4个BCB6的更新。
daydayup234 2008-05-22
  • 打赏
  • 举报
回复
看看 WideString::Copy
jxw1987628 2008-05-22
  • 打赏
  • 举报
回复
呵呵 学习中
daydayup234 2008-05-22
  • 打赏
  • 举报
回复
问题是C++不能分辨是BSTR还是wchar_t*

这个持续困扰我好久
HikerLive 2008-05-22
  • 打赏
  • 举报
回复
学习,关注!
过客猫2022 2008-05-22
  • 打赏
  • 举报
回复
procedure WideAssign(var dst: WideString; var src: WideString);
begin
dst := src;
end;
过客猫2022 2008-05-22
  • 打赏
  • 举报
回复
{ WideAssign is called from the C++ AnsiString's copy constructor, so it
must use pass-by-reference to avoid infinite recursion. This will
require ugly const_cast<>'s in the C++ caller }
procedure WideAssign(var dst: WideString; var src: WideString);
加载更多回复(18)

13,825

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder相关内容讨论区
社区管理员
  • 基础类社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧