0

用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

4

1 回答 1

4

问题在这里:

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

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

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

于 2012-07-12T06:14:17.703 回答