1

Cstring::Format 导致 Visual Studio 2008 中 vsprintf.c 第 244 行的调试断言出现“缓冲区太小”。

//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() 会导致“缓冲区太小”错误吗?这并不总是得到调试断言错误。

4

3 回答 3

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[]”时忘记执行的字符串中。

于 2012-08-10T05:09:55.763 回答
0

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

于 2012-08-10T02:26:03.807 回答
0

问题是CFile::Read()它不能保证它读取的数据与您要求的一样多。有时它读取的内容更少,并且让您的缓冲区没有空终止符。您必须假设每次读取调用可能只获得一个字节。当一个不可读的内存块紧跟着你的缓冲区时,这有时也会崩溃。

您需要继续阅读该文件,直到读完为止。此外,空终止符通常根本不会写入文件,因此您不应该假设它会被读入,而是要确保无论读取什么内容,您的缓冲区始终是空终止的。

此外,您不应该使用文件大小作为缓冲区大小;没有理由认为您可以一次阅读所有内容,并且文件大小可能很大或为零。

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

// 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;
        }
    }
}

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

于 2013-04-15T18:30:01.180 回答