用了很久COM了,一直老老实实为传出BSTR分配空间,今天做个实验,发现一个令人惊奇的事情:SysFreeString似乎什么都没有做。比如一个接口函数定义如下:
ITest:AAAA([out,retval]BSTR* pbstrTest)
在函数内这么写
{
  ……
  ……
  ……
  *pbstrTest = SysAllocString("This is A test");
  SysFreeString(*pbstrTest);
  return S_OK;
}在进程外调用该接口,居然可以正确得到"This is A test"。
对内存进行一番分析后,发现SysFreeString执行期间,这个BSTR的内容并未发生变化,就是说指针前的表达长度的4个字节没有变成0,当然指针所指的地址空间更没有被重写,所以仍然可以marshal,甚至你可以多次调用SysFreeString仍然不会影响进程外的调用。(进程内就更不用说了)个人觉得这个问题很奇怪,提出来,看看有没有高人能给个解答。

解决方案 »

  1.   

    SysFreeString释放内存给系统,并不负责清除内存(这有点多余)你不觉得
      

  2.   

    SysFreeString就和delete,free类似,只是负责把内存回收,但是不负责把内存的内容清空
      

  3.   

    SysFreeString表示回收内存,内存清空需要你自己作
      

  4.   

    在msvcrt里面,new操作实际上分配一个空间,然后将这块空间加入到纪录已经分配的内存的一个链表里面,delete就是负责在这个链表中去掉这块内存的纪录,他并不负责清空内存的!
      

  5.   

    不负责清除内存是对的,但是居然还可以任意访问,delete的指针就不行了
      

  6.   

    我觉得SysFreeString至少应该把长度减少成0吧?
    比如
    BSTR bstrTest = SysAllocString("This is A test");
    SysFreeString(bstrTest);
    UINT nLen = SysStringLen(bstrTest);
    nLen居然还是12我觉得这个真的很不安全,你访问了一个释放后的空间,系统没有检查,你完全不知道这个空间已经无效了,所以程序平时运行都是正确的,偶尔出一次错误,没谁知道是哪儿出问题了。
      

  7.   

    不管怎么说,我觉得系统还是应该做一些访问检查的,就像delete过的一样。不然这个实在是很危险。