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,则可以顺利调用该函数。
看来以后还是要仔细认真才行,之前只使用这些宏,没有仔细地考虑内存删除的问题,当然没有考虑,也就没有意识到这里面可能存在的问题。
这是经验?教训?
或许两者都有吧