C 当缓冲区溢出可能';事实上从未发生过

C 当缓冲区溢出可能';事实上从未发生过,c,visual-studio,visual-studio-2019,buffer-overrun,C,Visual Studio,Visual Studio 2019,Buffer Overrun,这是我的代码: void foo(int num) { int *pArr = (int *)malloc(num * sizeof(int)); // allocate array of 'sale' structs for each region for (int i = 0; pArr != NULL && i < num; i++) { pArr[i] = 1; } } int main() { int nu

这是我的代码:

void foo(int num) {
    int *pArr = (int *)malloc(num * sizeof(int));
    // allocate array of 'sale' structs for each region
    for (int i = 0; pArr != NULL && i < num; i++) {
        pArr[i] = 1;
    }
}

int main() {
    int num = 36;
    foo(num);
}
void foo(int num){
int*pArr=(int*)malloc(num*sizeof(int));
//为每个区域分配“销售”结构数组
for(int i=0;pArr!=NULL&&i
表达式
pArr[i]=1给出C6386警告

写入“pArr”时出现警告C6386缓冲区溢出:可写 大小为'num*sizeof(int)'字节,但可能写入'8'字节

这是非常奇怪的,因为
for
循环的迭代次数和头部数组的大小都取决于
num
,因此实际上永远不会发生溢出

然后有一个详细的解释:

i
可以等于1
pArr
可能为
NULL
(继续此循环)
pArr
的写入无效(超出其可写范围)

但这当然是visual studio的错误,
pArr
不能为
NULL
,因为这是进入循环的条件

如何清除此警告?

谢谢大家

出现这个问题是因为VS似乎无法推断如果pArr为空,循环将永远不会运行。将代码替换为

void foo(int num) {
    int *pArr = (int *)malloc(num * sizeof(int));
    
    if (pArr == NULL) {
        return;
    }
    
    // allocate array of 'sale' structs for each region
    for (int i = 0; i < num; i++) {
        pArr[i] = 1;
    }
}

int main() {
    int num = 36;
    foo(num);
}
void foo(int num){
int*pArr=(int*)malloc(num*sizeof(int));
if(pArr==NULL){
返回;
}
//为每个区域分配“销售”结构数组
for(int i=0;i

将解决您的问题并提高运行效率。

您可以进行一个简单的更改,以不再获得C6386警告。在尝试分配之前,您应该测试
num
的值。C语言标准有一个有趣的声明,关于将大小0传递给
malloc()

7.22.3内存管理功能

如果请求的空间大小为零,则行为为 实现定义:返回一个空指针来指示 一个错误,或者行为好像大小是某个非零值, 但返回的指针不得用于访问 反对

POSIX标准也有类似的规定:

如果大小为0,则:

应返回空指针,并且可将errno设置为 实现定义的值,或

应返回指向分配空间的指针。应用程序 应确保指针不用于访问对象

Microsoft的代码分析没有为此代码发出C6386:

void foo(int num)
{
    if (num == 0) { // avoid passing 0 to malloc()
        return;
    }
    int *pArr = (int *) malloc(num * sizeof(int));
    // allocate array of 'sale' structs for each region
    for (int i = 0; pArr != NULL && i < num; i++) {
        pArr[i] = 1;
    }
}
void foo(int num)
{
如果(num==0){//避免将0传递给malloc()
返回;
}
int*pArr=(int*)malloc(num*sizeof(int));
//为每个区域分配“销售”结构数组
for(int i=0;pArr!=NULL&&i
与问题无关:您无需检查
pArr!=空
for
loopTry
#pragma警告(disable:6386)
?注意:如果您在尝试分配之前为
num==0添加一个测试,警告将消失。您是如何得到此警告的?我尝试使用VS2019编译此代码,警告级别为4,但没有收到任何警告。在我的配置中禁用了代码分析(默认情况下)。我现在已经打开了它,我确实收到了这个警告。我已经尝试了你建议的代码,但它仍然会生成上面提到的警告。是的。避免0字节的malloc解决了这个问题。不过,VS给出的警告是神秘的,不便于用户使用。