【问题标题】:Difference between initializing a string with (char *)malloc(0) and NULL用 (char *)malloc(0) 和 NULL 初始化字符串的区别
【发布时间】:2015-08-06 12:14:43
【问题描述】:

为什么在这种情况下分配 0 大小的 char 块有效?但是如果我写char *string = NULL; 就不行了。

我正在使用 Visual Studio。

int main()
{   
    char *string = (char *)malloc(0);
    string[0] = 'a';
    string[1] = 'b';
    string[2] = 'c';
    string[3] = 'd';
    string[4] = '\0';

    printf("%s\n",string);
    return 0;
}

【问题讨论】:

标签: c string


【解决方案1】:

首先让我声明,根据malloc()man page

malloc() 函数分配 size 字节并返回一个指向已分配内存的指针。内存未初始化。 如果 size 为 0,则 malloc() 返回 NULL 或稍后可以成功传递给 free() 的唯一指针值。

malloc(0) 这样的调用本身是有效的,但是,我们需要检查返回指针的有效性。也可以

  • 返回NULL
  • 返回一个可以传递给free()的指针。

但无论如何,取消引用该指针是不允许的。会导致内存越界访问,导致undefined behaviour

也就是说,要提两件重要的事情,

  1. see why not to castmalloc()C中的family返回值。

  2. 在使用返回的指针之前,请检查malloc()的返回值。

所以,回答你的问题,

(char *)malloc(0)和NULL初始化字符串的区别

在这种情况下不要使用malloc(0),因为对指针的 N​​ULL 检查可能失败,给人以有效内存分配给指针。始终使用NULL 进行初始化。

【讨论】:

    【解决方案2】:

    上面的代码调用了未定义的行为。您分配的内存不足,正在访问无效地址。

    根据规范,malloc(0) 将返回“可以成功传递给 free() 的空指针或唯一指针”。

    【讨论】:

    • s/random/invalid。内存分配器的行为是非常不随机的,它会产生可怕的 PRNG。
    • @Quentin 但这是一个面向程序员的问答网站,如果有人给出答案,则应该正确表达。我也可以决定,从现在开始,我用“string”这个词来表示“function”,然后每次有人指出不能调用字符串时我都会抱怨我只用“string”和“function” "作为它的意思。有些人试图使用内存分配地址作为随机数的来源。我们不要鼓励传播感染(如果这些“随机”数字最终加密了您的 HTTPS 流量怎么办?您愿意吗?)
    • @Quentin 长大了。说真的,如果你没有看到正确表达某人所说的话的价值,我什至不想和你进一步争论。
    • @TheParamagneticCroissant 我什至不确定你为什么要争论。当然,对于不确定的地址,“无效”比“随机”要好。只是想到有人会因为“随机”这个词的存在而跳起来并试图从中做出 PRNG,这让我笑了起来。没有理由不高兴。
    【解决方案3】:

    malloc 定义:

    分配一块大小字节的内存,返回一个指向 块的开头。

    新分配的内存块的内容没有初始化, 剩下不确定的值。

    如果大小为零,则返回值取决于特定的库 实现(它可能是也可能不是空指针),但返回 指针不应被取消引用。

    取自here,发现this related question

    【讨论】:

    • 调用malloc(0) 不会导致未定义的行为,并且返回的地址也不是特别随机的。 (特别是要求它是唯一的。)
    猜你喜欢
    • 2014-07-26
    • 1970-01-01
    • 2018-04-29
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多