将项目从 vc6 升级到 vc9 后检测到堆损坏

Posted

技术标签:

【中文标题】将项目从 vc6 升级到 vc9 后检测到堆损坏【英文标题】:HEAP CORRUPTION DETECTED after upgrade the project from vc6 to vc9 【发布时间】:2012-07-12 05:48:17 【问题描述】:

用vc6编写的函数。

bool CProductionTestDlg::GetVariables(CString strFilename, CMapStringToOb *cVariableMap)

    int     iMaxEntryLen   = 1000;
    //char    rgbEntryNames[1000];                //previous
    char  *rgbEntryNames = (char*)malloc(iMaxEntryLen * sizeof(int)); //Now
    CString strEntryName   = "";
    CString strEntryValue  = "";
    UINT    uiSeperator    = 0;
    ULONG   dwRetCode, dwSizeOfReturn;

    dwSizeOfReturn = GetPrivateProfileString(cszVariables,
                                            NULL,
                                            "",
                                            rgbEntryNames,
                                            iMaxEntryLen,
                                            strFilename);

    while ( uiSeperator < dwSizeOfReturn )
    
        strEntryName.Format("%s", &rgbEntryNames[uiSeperator]);
        uiSeperator += strEntryName.GetLength() + 1;

        CString *strValue = new CString();
        dwRetCode = GetPrivateProfileString(cszVariables,
                                            strEntryName,
                                            "",
                                            strEntryValue.GetBufferSetLength(strEntryValue.GetLength()),
                                            iMaxEntryLen,
                                            strFilename);
        strValue->Format("%s", strEntryValue);        
        cVariableMap->SetAt(strEntryName, (CObject*)strValue);

    

    return true;

现在我在vs08上升级它。项目构建正确,但是当我打开exe时抛出异常

*检测到堆损坏 * CRT 检测到应用程序在堆缓冲区结束后写入内存。

当我调试我的应用程序时,控件在返回 true 后转到第 2103 行的 dbgheap.c

【问题讨论】:

我认为缓冲区 rgbEntryNames 太小了 我试过了,但问题依旧...... @Jeeva 看看我编辑的问题....... @vikky 使用调用堆栈窗口转到 CProductionTestDlg::GetVariables 的上下文。这样您将看到函数中的哪一行导致了异常。 【参考方案1】:

问题出在这里:

dwRetCode = GetPrivateProfileString(cszVariables, 
    strEntryName, 
    "", 
    strEntryValue.GetBufferSetLength(strEntryValue.GetLength()), 
    iMaxEntryLen, 
    strFilename);

你传递了一个大小为 0 的缓冲区(strEntryValue 被初始化为 ""),但说它的大小是 iMaxEntryLen。所以GetPrivateProfileString 认为它的缓冲区比它实际得到的要大得多,并且超出了它的界限。

升级后出现此错误的原因是,猜测是边界验证的改进。该错误在 VC6 中也存在,只是没有被检测到。

【讨论】:

以上是关于将项目从 vc6 升级到 vc9 后检测到堆损坏的主要内容,如果未能解决你的问题,请参考以下文章

将项目从 vc6 转换为 vc9 的问题

检测到堆损坏(动态数组)

在 dll 导出期间块之前检测到堆损坏

从 VC6 迁移到 VC9 的编译问题

字符串的动态数组,但我检测到堆损坏

释放 2D 数组 - 检测到堆损坏