小心使用_bstr_t类

在编写代码的时候用到_bstr_t这个类,调试代码过程中发现结果出人意料。

写了下面三句代码进行测试,发现bstr1、bstr2、bstr3三个变量执行到最后地址指向同一个地方,值都是"ijkl"。   
BSTR bstr1  = _bstr_t(L"abcd");
BSTR bstr2  = _bstr_t(L"efgh");
BSTR bstr3  = _bstr_t(L"ijkl");

再改成下面语句测试,发现bstr1还是等于bstr3,值为"ijkl",但bstr2却正常了,等于"efghabcd",好像和字符串长度有关。
BSTR bstr1  = _bstr_t(L"abcd");
BSTR bstr2  = _bstr_t(L"efghabcd");
BSTR bstr3  = _bstr_t(L"ijkl");

 

_bstr_t(xxx)返回的是_bstr_t的内部指针,可能会随时更改的.........
应该:
BSTR bstr1  = _bstr_t(L"abcd").copy();
BSTR bstr2  = _bstr_t(L"efgh").copy();
BSTR bstr3  = _bstr_t(L"ijkl").copy();

 

对于 BSTR bstr1  = _bstr_t(L"abcd").copy();
这是通过SysAllocStringLen分配新的内存。
用完需要 SysFreeString(bstr1);

 

_bstr_t(L"abcd"); 这只是临时构造了一个_bstr_t对象,该构造函数内会通过SysAllocString来给BSTR分配内存。
在把BSTR的指针返回给 bstr1 之后,就会释放_bstr_t这个临时对象,在其析构函数里就把分配给BSTR的内存释放了。

在执行_bstr_t(L"efgh"); 又临时构造一个,这个时候,没有别的申请过内存,_bstr_t临时对象内给BSTR分配的内存又是上一次给的那块内存。并把内容更改 efgh。
也就是bstr2 指向的内存和 bstr1变量指向的内存地址 是相同的。

_bstr_t(L"ijkl"); 的过程也是一样,最终三者指向的内存地址是一样的。


对于后面那种情况,因为第二个的字符串长度长了,分配的内存刚好在另外一个位置了。
而给第三个bstr分配内存刚好在第一个的原来位置

 

 

你可能感兴趣的:(测试)