MSVC C6029 警告:缓冲区可能溢出,使用未经检查的值.检查缓冲区大小时,警告不会消失
MSVC C6029 Warning: possible buffer overrun, use of unchecked value. The warning does not disappear when checking the buffer size
我的代码中有烦人的C6029警告(Microsoft网站上的错误描述(。
例如:
#include <cstdio> // fopen, fseek, fread, fclose
static constexpr size_t MAX_BUFFER_SIZE = 100;
void foo(const FILE* myFILE)
{
double buffer[MAX_BUFFER_SIZE]{};
size_t bufferSize = 0;
std::fread(&bufferSize, sizeof(size_t), 1, myFILE);
std::fread(buffer, sizeof(double), bufferSize, myFILE); // C6029 Warning.
}
仅当观察到一个特定的检查时,它才会消失(如错误描述中的示例(:
#include <cstdio> // fopen, fseek, fread, fclose
static constexpr size_t MAX_BUFFER_SIZE = 100;
void foo(const FILE* myFILE)
{
double buffer[MAX_BUFFER_SIZE]{};
size_t bufferSize = 0;
std::fread(&bufferSize, sizeof(size_t), 1, myFILE);
if(sizeof(double) * bufferSize > sizeof(buffer))
{
return;
}
std::fread(buffer, sizeof(double), bufferSize, myFILE); // No C6029 Warning.
}
这样的解决方案不适合我,因为如果超过允许的值,我仍然需要从文件中读取其他内容。
但是,如果我检查等效情况,警告仍然存在:
#include <cstdio> // fopen, fseek, fread, fclose
static constexpr size_t MAX_BUFFER_SIZE = 100;
void foo(const FILE* myFILE)
{
double buffer[MAX_BUFFER_SIZE]{};
size_t bufferSize = 0;
std::fread(&bufferSize, sizeof(size_t), 1, myFILE);
if(sizeof(double) * bufferSize <= sizeof(buffer))
{
std::fread(buffer, sizeof(double), bufferSize, myFILE); // C6029 Warning, again.
}
}
同时,如果您稍微修改Microsoft建议的检查以发生错误,警告将神奇地消失:
#include <cstdio> // fopen, fseek, fread, fclose
static constexpr size_t MAX_BUFFER_SIZE = 100;
void foo(const FILE* myFILE)
{
double buffer[MAX_BUFFER_SIZE]{};
size_t bufferSize = 0;
std::fread(&bufferSize, sizeof(size_t), 1, myFILE);
if(sizeof(double) * bufferSize <= sizeof(buffer))
{
// DO NOTHING...
}
std::fread(buffer, sizeof(double), bufferSize, myFILE); // Wow, magic! No C6029 Warning.
}
此错误警告让我非常恼火。当然,我根本不能注意它,但我仍然想以"合法"的方式摆脱它(最好在语法上不可怕(。
这样的解决方案不适合我,因为如果允许的值是 超过,我仍然需要从文件中读取其他内容。
然后不要std::fread
没有缓冲区的有问题的部分。例如,您可以std::fseek
它。或者,您可以动态分配足够大的缓冲区。
如果输入文件中的数据太大,您发布的第一个版本的foo
将溢出缓冲区。 因此,编译器发出警告是非常正确的。
最好的解决方案可能是动态分配缓冲区(为简洁起见,省略了错误检查(:
void foo(FILE* myFILE)
{
double *buffer;
size_t bufferSize = 0;
std::fread(&bufferSize, sizeof(size_t), 1, myFILE);
buffer = new double [bufferSize];
std::fread(buffer, sizeof(double), bufferSize, myFILE);
...
delete [] buffer;
}
注意:不能将myFILE
作为const
传递 - fread
需要修改对象。 此外,在这种情况下,结帐std::unique_ptr
协助内存管理。
相关文章:
- 警告处理为错误这里有什么问题
- C++字符*缓冲区的大小
- 为什么msgrcv()将垃圾字符馈送到缓冲区
- 使用动态分配的数组会导致代码分析发出虚假的C6386缓冲区溢出警告
- ostream过载时的缓冲区冲洗
- C++中的高效循环缓冲区,它将被传递给C样式数组函数参数
- cppcheck在const std::string[]上引发警告
- GCC对可能有效的代码抛出init list生存期警告
- 如何在BST的这个简单递归实现中消除警告
- Xaudio2在更改缓冲区或循环时弹出声音
- 关于std::move的使用,是否有编译警告
- g++ 在某个类成员未初始化时不发出警告
- 为什么我在leetcode上收到AddressSanitizer:地址0x602000000058上的堆缓冲区溢出错误
- 如何将图像传输到c++(dll)中的缓冲区,然后在c#的缓冲区中读/写
- 如何在cpp.中使用协议缓冲区存储大缓冲区/数组(char/int)
- OpenGL 调试上下文警告 -"将使用视频内存作为缓冲区异议的来源
- MSVC C6029 警告:缓冲区可能溢出,使用未经检查的值.检查缓冲区大小时,警告不会消失
- 为什么缓冲区超支警告(C4789)仅在编译器标志 /o2中发生
- 为什么在Visual Studio 2012上的代码分析中,此代码会发出缓冲区溢出警告(C6385/C6386)
- 是什么原因导致此缓冲区溢出警告超过64位VS2012编译环境