今天在调试程序时发现这个函数似乎有bug? TCHAR strNumber[MYSTRINGLEN] = {'\0'};
swprintf_s(strNumber,MYSTRINGLEN,L"%lu",m_Axis1.dwYUpper);看起来似乎没有问题,但是调试时却发现swprintf_s()完全是越界访问了,而且把strNumber[]后面的一个窗口句柄变量都改写掉了!
未执行字符串写入操作前的数组:执行了函数操作后的字符串数组--的确获得了整形数值1500,但是后面却被莫名其妙地写入了65278?
居然写过了行末?
谁研究过这个吗?
我还发现如果改为memcpy_s()来实现字符串拷贝则不再出现越界写操作了?很奇怪的说?

解决方案 »

  1.   

    是ansi与unicode混用造成的.    wchar_t strNumber[MYSTRINGLEN] = {'\0'};
        swprintf_s(strNumber,MYSTRINGLEN,L"%lu",m_Axis1.dwYUpper);
      

  2.   

    我的项目全是Unicode编码的,因为都是VS2008下面的,所以里面的TCHAR系统全部都是这样定义的
    typedef WCHAR TCHAR, *PTCHAR;
    不单是swprintf_s()有这个问题,还有_itow(),_itow_s()全部都会自动越界访问,根本无法控制。
      

  3.   

    int _snwprintf(
       wchar_t *buffer,
       size_t count,
       const wchar_t *format [,
       argument] ... 
    );TCHAR strNumber[MYSTRINGLEN] = {'\0'};
    swprintf_s(strNumber,MYSTRINGLEN,L"%lu",m_Axis1.dwYUpper);// 问一下,MYSTRINGLEN的值是多少?
      

  4.   

    swprintf_s(strNumber,MYSTRINGLEN,L"%lu",m_Axis1.dwYUpper);
    这个函数其实是“畸形”的因为他会首先依据MYSTRINGLEN的大小,使用memset()将strNumber指针指向的区域设置为0.如果MYSTRINGLEN的长度大于strNumber的实际长度,则内存越界就是必然的。建议使用<strsafe.h> 中的 StringCchPrintf(...)
      

  5.   

    好像又不越界了。我把数组尺寸弄长了一些,只操作前面的MYSTRINGLEN-4个就好了。但是今天的的确确发现它越界了,要不然就不会发生窗体的句柄被莫名其妙地改写了,也就不会在调试中发现这个问题了。反正我感觉这些个函数后面加了_s,其实也并不save-_-!
      

  6.   

    如果你的MYSTRINGLEN比数组实际长度大,那么程序退出后会有提示的Run-Time Check Failure #2 - Stack around the variable 'xx' was corrupted.
      

  7.   

    既然你用了TCHAR,那么就用_stprintf_s、_itot_s()……
    stprintf_s(strNumber,MYSTRINGLEN,_T("%lu"),m_Axis1.dwYUpper);
    如果都配套的话,应该不会出现这种问题吧。因为像swprintf类的函数,locale、参数的类型设置什么的都会产生复杂的影响。不要用这种混合代码。4楼说的有问题,既然用MYSTRINGLEN定义的数组,而且微软的实例也是那样的,况且溢出的也不是0而是65278……
      

  8.   

    既然用了TCHAR,就应该全带t的版本,如果你只用Unicode的话,就全用wchar_t和带w的版本。否则只会让问题复杂化。
    另外的VS装了SP1了么,也可能是bug。