我有这部分代码:
class CNuovoVocabolo {
CString m_strItaliano;
CString m_strRusso;
//...
}
void CNuovoVocabolo::GetVocabolo( CVocabolo* pVocabolo )
{
int nLIta;
int nLRus;
wchar_t *pIta;
wchar_t *pRus;
nLIta = m_strItaliano.GetLength();
nLRus = m_strRusso.GetLength();
if( nLIta > 0 && nLRus > 0 )
{
pIta = new wchar_t[nLIta + 1];
wcscpy_s( pIta, nLIta * sizeof( wchar_t ), m_strItaliano );
pRus = new wchar_t[nLRus + 1];
wcscpy_s( pRus, nLRus * sizeof( wchar_t ), m_strRusso );
pVocabolo->SetVocabolo( pIta, nLIta, pRus, nLRus );
delete [] pIta; // *1
delete [] pRus; // *2
}
}
// Inside CVocabolo::SetVocabolo:
void CVocabolo::SetVocabolo( const wchar_t* pIta/*=NULL*/, unsigned short nLIta/*=0*/, const wchar_t* pRus/*=NULL*/, unsigned short nLRus/*=0*/ )
{
if( pIta != NULL && pRus != NULL && nLIta > 0 && nLRus > 0 )
{
AzzeraVocabolo();
m_nLIta = nLIta;
m_nLRus = nLRus;
m_pItaliano = new wchar_t[nLIta + 1];
wcscpy_s( m_pItaliano, nLIta * sizeof( wchar_t ), pIta );
m_pRusso = new wchar_t[nLRus + 1];
wcscpy_s( m_pRusso, nLRus * sizeof( wchar_t ), pRus );
}
}
当我在* 1和* 2处删除pIta指针和pRus指针时,由于堆损坏而导致崩溃。老实说,我不明白为什么会这样,我做错了。有什么建议吗?
修改:
在网上看,我找到了解决方案:
pIta = new wchar_t[( nLIta + 1 ) * sizeof( wchar_t )];
但说实话,对我来说还不清楚。如果你能给我一个解释...... 此外,知道为什么问题被低估了。
答案 0 :(得分:1)
问题出在这里。
pIta = new wchar_t[nLIta + 1];
wcscpy_s( pIta, nLIta * sizeof( wchar_t ), m_strItaliano );
在第一行中,size是一个宽字符数组加上一个null终止符。这是正确的。
在第二行中,所需的大小是字符数加上null,但是你通过乘法给它一个更大的数字。这是错误的。
如果这些是short
个字符和20个字符的字符串,则第一个参数是21,第二个参数是40(它也应该是21)。这本身就是一个无声的错误。不幸的是,在DEBUG构建中(假设您正在使用),wcscpy_s函数填充整个缓冲区,整齐地覆盖未分配的内存。
你的修复工作的原因是你(错误地)使缓冲区足够大以容纳(错误的)长度副本,并且两个wongs变成白色(oops!)。
修复1:删除sizeof的乘法,并为null添加1。
修复2:停止使用这些可怕的函数,并开始使用wstring等编写一些优秀的C ++。
编辑:允许目的地为空。 (糟糕)