c++ - MSVC C6029 警告:可能的缓冲区溢出,使用未经检查的值。检查缓冲区大小时警告不会消失
问题描述
我的代码中有烦人的 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.
}
}
同时,如果你稍微修改微软推荐的检查,导致出现错误,警告就会神奇地消失:
#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.
}
这个错误警告让我非常恼火。当然,我可以根本不注意它,但我仍然想以“合法”的方式摆脱它(最好不要在语法上很糟糕)。
解决方案
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
as const
-fread
需要修改对象。此外,在这种情况下,结帐std::unique_ptr
以协助内存管理。
推荐阅读
- windows - PostgreSQL 版本 11.8 是否支持导入在 PostgreSQL 版本 8.4.20 中创建的数据库?
- c++ - 嵌入式节点执行 .node 文件
- azure - Azure B2C 调用 azure 函数,并将 JWT 令牌或代码保留为策略密钥
- apache-spark - 两列之间的部分匹配
- jaxb - Jaxb 解组卡住的线程 XMLDocumentScannerImpl$PrologDriver.next
- batch-file - 删除第一行中最后一次出现所选字符后的所有内容
- asp.net - Cookies 的 SameSite=None 设置丢失
- python - 在 python Tkinter 中发送电子邮件时能够更改地址
- javascript - JS - 在继续下一部分之前未能正确解决一系列承诺
- excel - 如何在 v 查找中使用变量而不是硬编码