strcpy_s, wcscpy_s, _mbscpy_s 用注意overlap

来源:互联网 发布:name和xyz域名哪个好 编辑:程序博客网 时间:2024/05/16 11:13

大家看到这些函数时,觉得这些再普通不过了,不过还是得耐心的看msdn的解释, 注意有一句话要重视: 

The strcpy_s function copies the contents in the address of strSource, including the terminating null character, to the location specified by strDestination. The destination string must be large enough to hold the source string, including the terminating null character.The behavior of strcpy_s is undefined if the source and destination strings overlap.

上面的红体字是要注意的地方,因为undefined的行为引起的bug/crash往往是很难重现的,造成系统不稳定:

比如这段代码: 

// 对一段字符串进行字符串左边修剪操作,修剪掉空格等字符

bool TestCpyString::TrimLeftInvalidChars(const TCHAR* strOldLine, TCHAR* strNewLine, int len)
{
if(NULL == strOldLine|| NULL == strNewLine) return false;
_tcscpy_s(strNewLine, len, strOldLine);     // 将原来的字符串拷贝新的地方(strNewLine)

TCHAR* pChar = NULL;
pChar = strNewLine;  // 记住现在的位置

// 碰到要修剪的字符就跳过去,这样我们就到达了要拷贝的位置上了
while(*pChar == _T(' ') || *pChar == _T('\t') || *pChar == _T(''))
{
pChar++;
}

        // 将需要拷贝的字符串拷贝过来
_tcscpy_s(strNewLine, len, pChar);     // 这里就出现了源字符串和目标字符串的重叠的问题,这样后果是未知的.

return true;
}


更改过后是:


bool TestCpyString::TrimLeftInvalidChars(const TCHAR* strOldLine, TCHAR* strNewLine, int len)
{
if(NULL == strOldLine|| NULL == strNewLine) return false;

TCHAR* pChar = NULL;
pChar = const_cast<TCHAR*>(strOldLine);  // 记住现在的位置

// 碰到要修剪的字符就跳过去,这样我们就到达了要拷贝的位置上了
while(*pChar == _T(' ') || *pChar == _T('\t') || *pChar == _T(''))
{
pChar++;
}

        // 将需要拷贝的字符串拷贝过来
_tcscpy_s(strNewLine, len, pChar);     // 源字符串和目标字符串没有重叠的问题

return true;
}


共勉!


原创粉丝点击