c++ - 在 Visual C++(缓冲区溢出)中处理 C6386 的“正确”方式?
问题描述
我有一个触发缓冲区溢出警告的代码片段:
void foo(unsigned int m, int n, unsigned int x, unsigned int y) {
unsigned int a[50][50];
memset(a, 0, 50*50*sizeof(unsigned int));
unsigned char odd = (x + y) % 2;
for (int dummy = 0; dummy < n; ++dummy)
{}
for (int row = 0; row < m; ++row) {
for (int col = (odd+row+1)%2; col < n; col += 2)
a[row][col] = 0;
}
}
触发警告的线是a[row][col] = 0;
它认为col
可能变为负面的地方。如果我执行以下任何操作,警告就会消失:
- 包含
&& col >= 0
在 for 语句中(它向循环添加了不必要的检查,因为在实际代码中我已经检查了变量边界并且知道我永远不会溢出) - 删除
for
代码片段中间的虚拟循环(很奇怪,我知道,并且在“虚拟”循环正在执行实际工作的真实代码中) - 更改
dummy
为 size_t (奇怪,与带有警告的循环无关) - 更改
n
为unsigned int
(同样,很奇怪,与所讨论的循环无关) - 从初始化程序中删除
odd
变量col
(这会使代码不正确) - 使用#pragma 忽略问题(我通常更愿意避免)
不起作用的事情:
- 检查 for 循环上方的任何地方是否有可能导致溢出的范围(我尝试了范围检查
m
,n
,x
,y
, 甚至odd
)。 - 更改
col
为像 size_t 这样的无符号类型,或进行任何类型的无符号转换
没有一种解决方法让我感到温暖和模糊。我最近经常看到这样的警告,通常是对不相关的代码位的古怪依赖,比如for
这里看到的虚拟循环,而且几乎从不暴露真正的问题。是否有避免此类警告的最佳做法?
解决方案
推荐阅读
- java - Intellij Idea 无法执行 git pre-push hook
- scala - 试图在scalafx中获取用户最新的鼠标点击
- javascript - 如何将多个对象串行推入一个对象
- string - XSLT 中的整数到字符串的转换
- android - 如何解决 Qt Creator 中 Android 项目的构建错误“找不到 -lc++”?
- mysql - 声明变量的默认值是否始终为空?
- android - ViewPager 中的视频没有暂停
- vue.js - 如何在 vuejs 中将 $ref 设置为来自父组件的子组件元素?
- .net - LINQ 查询以获取最低和最高价格范围内的所有产品?
- bash - 将单个变量中的值列表视为多个单独的值 (bash)