Malloc 总是 returns 一个 NULL 指针; Visual Studio 2022

Malloc always returns a NULL pointer; Visual Studio 2022

这可能是一个重复的问题,但我检查了其他类似的问题,但从未真正找到我要找的东西(或者我相信)。

考虑以下代码:

#include <iostream>
#include <stdlib.h>

int main()
{   
    char* s = (char*)malloc(2 * sizeof(char));

    *s = 'M';

    s++;

    *s = 'I';

    std::cout << s[-1] << s[0] << s[1];
}

输出:

MI²

我的问题是,每当我尝试使用 malloc/calloc/realloc 时,我总是会弹出相同的错误消息,提示 s(参见上面的代码) 是一个 'unreferenced NULL-pointer'.

我真的看不出这里有什么问题。特别是因为 'M' 和 'I' 都已分配给我通过 malloc 初始化的数组,但它们位于奇怪的位置。我期望:s[0] = 'M' 和 s[1] = 'I' 但实际上是 s[-1] = 'M's[0] = 'I',我觉得这很奇怪。

我哪里错了?

你不应该在行 s++;
中更改 s s 指向您分配的基础。所以当你增加它时,s[0] 指向 'I'.

是很自然的

如果您想分配内存分配的第二个位置,或者就此而言的第 i 个位置,您可以使用此 s[i] = 'M';,或者您可以这样做:*(s+i) = 'M';。\

但前者是更好的做法,因为它更具可读性。我相信大多数人在面对后者时都会停下来,因为现在已经很少见了。

附加信息

事实上,当你使用s[i] = 'M';时,编译器只是将它翻译成*(s+i) = 'M';。所以这个 [] 只是一个在指针类型上定义的运算符,它只是将其参数(在大多数情况下名为 i )添加到指针的基址。

需要说明的是,该消息是编译器发出的警告,并不是您从 malloc 中获取 null,它警告您可能并没有检查

https://docs.microsoft.com/en-us/cpp/code-quality/c6011?view=msvc-170

如果您这样做,消息就会消失

char* s = (char*)malloc(2 * sizeof(char));
if (s != NULL)
{
    *s = 'M';

    s++;

    *s = 'I';

    std::cout << s[-1] << s[0] << s[1];
}

虽然还有另一个警告

https://docs.microsoft.com/en-us/cpp/code-quality/c6200?view=msvc-170

这是警告 s[-1] 看起来很奇怪。它忽略了你之前做过 s++ 的事实,这使得这没问题。

不好的是

 std::cout << s[-1] << s[0] << s[1];
 ------------------------------*****

这是在分配结束后访问数据,结果是未定义的行为。

如果你这样做

int main()
{
    char* s = (char*)malloc(2 * sizeof(char));
    if (s != NULL)
    {
        s[0] = 'M';

        

        s[1] = 'I';

        std::cout << s[0] << s[1] << s[2];
    }
}

这是做同样事情的更直接的方法,然后 VS 会警告你 s[2] 越界