3

这是我的代码:

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

该表达式pArr[i] = 1;给出 C6386 警告

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

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

然后有一个详细的解释:

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

但这当然是视觉工作室的错误,pArr不可能NULL,因为这是进入循环的条件。

如何清除此警告?
谢谢你们

4

2 回答 2

1

您可以进行一个简单的更改以不再收到 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;
    }
}
于 2021-01-03T18:59:45.693 回答
0

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

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

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

于 2021-01-03T17:49:30.757 回答