USES_CONVERSION 害得我好苦

之前用过很多次


USES_CONVERSION,然后可以方便地使用A2W、W2A来转换字符串的宽、窄,相当顺手,感觉这两个宏太好用了。如今我继续用它。


我写好了程序,写的时候已经很注意了,由于之前吃过堆栈溢出的亏,所以在定义变量时非常小心,稍大一些的内存都使用了new来分配。

程序完工之后,运行,有时候会报错挂掉,短的半小时就挂了,长的1天多挂,没啥规律,有时效动它挂掉,有时间不动它也挂掉。

程序分了3层,底层为SDK,由VC++编写,中间为ocx控件,也由VC++编写,上层为exe,由C#编写。

跟踪可以在SDK层,也可以在ocx层。由于无法直接调试,只能先启动exe,然后在SDK或者ocx的工程上附加到该exe上进行调试。

经过数次跟踪,终于发现挂掉是因为堆栈,也跟踪到了对应的函数,但该函数相当简单,还不到20行代码,再3检查,不可能出问题的。


没办法,检查其它的函数,倒是找了几个可能的问题出来,但都不像和这个挂掉的问题相关,然后找同事过来帮忙查看,指着一行代码:

USES_CONVERSION;
BSTR jsonstring = A2W(avInfoPtr->cmdInfo.cmd_str);

说,可能就是这一行的问题了。

我晕,这个用过很多次了,从来没有出过问题。不过还是仔细想一下,每次都是大数据量时挂掉,从来没有哪次是小数据时挂的,所以也有点怀疑是这一行引起的。然后查看msdn的A2W帮助,上面有一行:

If it is known that the converted string is unlikely to be more than 64 characters, the EX version, such as CW2CTEX<64>, can be used to save space on the stack.

请注意到最后个单词stack。原来这个宏是在栈上分配内存的 @##!@$%^^&&&*

后去网上查了一下,果然发现有人提出要注意这个宏的使用,再然后自己写了个函数来验证


void mytest()

{

  int len = 1024;
  char *cmdar = new char[len];
  memset( cmdar, 0, len );
  for ( int im = 0; im < len - 1; im++ )
  {
   cmdar[im] = im%255 + 1;
  }

  BSTR jsonstring = A2W(cmdar);

}

如果我把len增加到1MB时,调用该函数出现的情况和原工程中的完全一样,确实是堆栈流出,如果我保持较小的len,则可以顺利调用该函数。


看来以后还是要仔细认真才行,之前只使用这些宏,没有仔细地考虑内存删除的问题,当然没有考虑,也就没有意识到这里面可能存在的问题。


这是经验?教训?

或许两者都有吧

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值