CString :: Format()导致调试断言

时间:2012-08-10 02:19:09

标签: visual-c++ mfc cstring

Cstring :: Format在vsprintf.c第244行的visual studio 2008中导致调试断言,“缓冲区太小”。

//inside the function.

somefile.Open (//open for mode read) //somefile is CFile.

char* buff = new [somefile.GetLength()];

somefile.Read ((void*)buff, somefile.GetLength());

CString cbuff;
cbuff.Format ("%s",buff); //this line causes the debug assertion.

//and so on 

知道为什么CString :: Format()导致“缓冲区太小”错误?这并不总是会出现调试断言错误。

3 个答案:

答案 0 :(得分:3)

另一种解决方案是:

somefile.Open (//open for mode read) //somefile is CFile.
int buflen = somefile.GetLength();

CString cbuff;
somefile.Read ((void*)cbuff.GetBuffer(buflen), buflen);
cbuff.ReleaseBuffer();

它直接读入字符串缓冲区而不是中间变量。 CString :: GetBuffer()函数会自动将额外的字节添加到您分配“new char []”时忘记执行的字符串。

答案 1 :(得分:0)

字符串以'\ 0'结尾 所以缓冲区大小不够

答案 2 :(得分:0)

问题是CFile::Read()并不能保证它能够读取您要求的数据量。有时它读取的次数较少,而且没有空终止符就会留下缓冲区。您必须假设每次读取调用只能获得一个字节。当有一个不可读的内存块紧跟在你的缓冲区之后,这也会有时崩溃。

您需要继续阅读文件,直到结束。此外,null终止符通常根本不写入文件,所以你不应该假设它会被读入,而是确保你的缓冲区总是以null结尾,无论读取什么。

此外,您不应将文件大小用作缓冲区大小;没有理由认为你可以一次性阅读,文件大小可能很大,或者为零。

您还应该避免手动内存管理,而不是new[] / delete[],而是使用向量,这将确保您不会忘记释放缓冲区或使用delete而不是delete[],即使在异常情况下也会释放内存。 (我不建议使用CStringCFile,但这是另一个话题......)

// read from the current file position to the end of
// the file, appending whatever is read to the string
CString ReadFile(CFile& somefile, CString& result)
{
    std::vector<char> buffer(1024 + 1);
    for (;;)
    {
        int read = somefile.Read(&buffer[0], buffer.size() - 1);
        if (read > 0)
        {
             // force a null right after whatever was read
             buffer[read] = '\0';

             // add whatever was read to the result
             result += &buffer[0];
        }
        else
        {
             break;
        }
    }
}

请注意,此示例中没有错误处理。