我有一个自定义字符串类,内部是malloc / realloc / free;对于某些字符串附加工作正常,但在某些其他字符串上它将始终失败(小或大分配)。相同的代码在不同的项目上运行良好,尽管它是ANSI构建。
我相信我正确地实现了这一点,但很可能我忽视了一些事情。打开日志后,当我尝试使用“szLog”缓冲区时,会发生错误。这只包含程序文件目录的路径(总共40个字符)。使用没有“日志文件”前缀的相同缓冲区工作正常,因此这是realloc部分的问题。是的,日志确实打开了。
我得到 0xC0000005:访问冲突读取位置0x00660063。仅在使用realloc时(但如前所述,它并不总是失败 - 在这种情况下,当输入szLog时 - 但是其他变量字符串/缓冲区也这样做。)
HeapReAlloc 是realloc.c中的失败函数,errno为22。
我已经删除了评论,试图让帖子尽可能小!任何帮助将不胜感激。
gData.szLogStr 是UString, IsNull 是“ x == NULL ”和 unichar 只是wchar_t
的typedefclass UString : public Object
{
private:
unichar* mpsz;
unichar* mpszPrev;
UINT muiAlloc;
UINT muiLen;
public:
... other functions ...
UString& operator << (const unichar* pszAdd)
{
if ( IsNull(pszAdd) )
return (*this);
if ( IsNull(mpsz) )
{
muiAlloc = ((str_length(pszAdd)+1) * sizeof(unichar));
if ( IsNull((mpsz = static_cast<unichar*>(malloc(muiAlloc)))) )
{
SETLASTERROR(ERR_NOT_ENOUGH_MEMORY);
muiAlloc = 0;
return (*this);
}
mpszPrev = mpsz;
muiLen = str_copy(mpsz, pszAdd, muiAlloc);
}
else
{
UINT uiNewAlloc = (muiAlloc + (str_length(pszAdd) * sizeof(unichar)));
if ( muiAlloc < uiNewAlloc )
{
uiNewAlloc *= 2;
/* Fails */
if ( IsNull((mpsz = static_cast<unichar*>(realloc(mpsz, uiNewAlloc)))) )
{
SETLASTERROR(ERR_NOT_ENOUGH_MEMORY);
mpsz = mpszPrev;
return (*this);
}
mpszPrev = mpsz;
muiAlloc = uiNewAlloc;
}
muiLen = str_append(mpsz, pszAdd, muiAlloc);
}
return (*this);
}
这是从主要通道内调用的:
UString szConf;
unichar szLog[MAX_LEN_GENERIC];
szConf << ppszCmdline[0];
szConf.replace(_T(".exe"), _T(".cfg"));
if ( GetPrivateProfileString(_T("Application"), _T("LogFile"), NULL, szLog, sizeofbuf(szLog), szConf.str()) == 0 )
{
UINT uiLen = str_copy(szLog, szConf.str(), sizeofbuf(szLog));
szLog[uiLen-3] = 'l';
szLog[uiLen-2] = 'o';
szLog[uiLen-1] = 'g';
}
if ( ApplicationLog::Instance().Open(szLog, CREATE_ALWAYS) )
{
gData.szLogStr.clear();
/* Erroring call */
gData.szLogStr << _T("Log file '") << szLog << _T("' opened");
APP_LOG(LL_WriteAlways, NULL, gData.szLogStr);
ObjMgr::Instance().DumpObjects(LogDumpedObjects);
}
答案 0 :(得分:1)
您使用c ++编程,因此请使用new
和delete
。要“更新”,请分配一个足够大的新内存区域来容纳新字符串,使用正确的值初始化它,然后delete
旧字符串。
答案 1 :(得分:0)
什么是str_length()失败时返回?我会追踪muiAlloc的价值,看看你真正想要分配什么。它可能不是一个理智的数字。
你确定szLog中的任何内容都是以null结尾的,并且缓冲区有空间容纳你复制到它的任何内容吗?目前尚不清楚str_copy是否安全。它可能是strncpy()的包装器,它不保证null终止符,但有些人错误地认为它有。