【问题标题】:If you use NULL as parameter of malloc(sizeof()), does it return NULL?如果使用 NULL 作为 malloc(sizeof()) 的参数,它是否返回 NULL?
【发布时间】:2022-01-12 01:16:39
【问题描述】:

我希望在这里听起来不是很愚蠢,但是 NULL 模块在执行此操作时是否真的需要内存分配:

TheNull = malloc(sizeof(NULL));

如果是真的,内存中怎么可能存在没有分配内存的东西呢?

【问题讨论】:

  • 在架构 WORD 大小中,NULL 通常不是定义为 0 吗?
  • NULL 保证为值为0(void *)0 的整数常量。我不会指望所有这些都与sizeof(void*) 相同。
  • @ikegami: NULL 可以是任何值为零的整数常量表达式,包括不是整数常量的表达式,尽管我不知道为什么有人会这样做。
  • TheNull = malloc(sizeof(NULL)); 这是你写的东西,还是你在别人的代码中找到的东西?或者它是您为了询问而发明的假设示例?无论如何,它要么是错误的,要么是毫无意义的。
  • @AndrewHenle:根据 C 2018 6.3.2.3 3,空指针常量 是“值为 0 的整数常量表达式,或此类表达式转换为 @987654330 类型@”。 “implementation-defined”部分表示实现可以将NULL定义为(3*4 - 12)(void *) (3*4 - 12);特定的表达式是灵活的,但它必须是值为 0 的整数常量表达式或转换为 void * 的此类表达式这一事实并不灵活。

标签: c memory-management malloc


【解决方案1】:

如果你使用NULL作为malloc(sizeof())的参数,它是否返回NULL

不,除非内存不足,就像任何其他分配一样。

NULL空指针常量,没有特定的类型。它可能是void *intlong 或某个整数类型。

避免使用sizeof(NULL),因为它的大小/类型可能因系统而异。

【讨论】:

    【解决方案2】:

    表达式与任何NULL 模块NULL 对象 没有任何其他关系。反正没有这样的东西。

    NULL 只是一个有用的空指针常量定义。

    C 标准以这种方式指定在 <stddef.h> 和其他一些标准头文件中定义的 NULL 宏:

    7.19 常用定义
    [...]
    宏是 [...]
    NULL
    它扩展为实现定义的空指针常量 [...]

    空指针常量在6.3.2.3中定义:

    6.3.2.3 指针
    [...]
    3.值为 0 的整型常量表达式或转换为 void * 类型的表达式称为空指针常量。67) 如果将空指针常量转换为指针类型,则结果指针,称为空指针,保证不等于指向任何对象或函数的指针。


    67) 宏 NULL (和其他头文件)中定义为空指针常量;见 7.19。

    许多目标定义NULL 被定义为#define NULL ((void *)0),而其他目标只使用#define NULL 0,或者可能是其他一些零整数常量表达式(例如:0L0UL...)。

    因此malloc(sizeof(NULL))尝试分配与NULL定义中表达式类型对应的字节数,可能是void指针的大小,但绝不是0字节。

    是否成功取决于可用内存:

    • 如果成功,返回值将是一个有效的指针,不同于NULL

    • 如果malloc(sizeof(NULL)); 确实返回NULL,这意味着没有可用的内存来分配非常小的大小,这是一个应该向用户报告并小心处理的危急情况。

    【讨论】:

    • 空指针常量可以是任何整数常量表达式,而不仅仅是int整数常量表达式。
    • 而且它不一定是零……
    • Re "它不一定是零",是的。 “值为 0 的整数常量表达式,或转换为 void * 类型的此类表达式,称为 空指针常量。如果将空指针常量转换为指针类型,则生成的指针,称为 null 指针,保证与指向任何对象或函数的指针进行比较。"所以说 C18,在 C11 和 C99 中有相同或相似的东西。我没有再往后看了。一旦将它转换为指针,它可能不再为零(尽管仍等于 0),但这里没有转换(隐式或非隐式)。
    • @chqrlie,哦,你说的是那个。那是无关紧要的。无论是否为 NULL,指针的大小都是相同的。我们在这里不关心这个。这是另一种可能性——当它不被转换为指针时——值得一提。
    • @chqrlie 我会将标准对空指针常量的定义解释为详尽无遗,即,如果它可能不是零整数表达式或此类转换为指针的表达式,那么标准将说吧。所以实现定义的部分,IMO,只允许实现选择整数表达式/类型以及是否转换它,但不允许整数值不是零。无论如何,关于 stackoverflow.com/questions/2599207/… 有一个单独的问题
    【解决方案3】:

    TheNull = malloc(sizeof(NULL));

    这不会分配 0 字节(因为 sizeof(NULL) 不为零),但 malloc(0) 可能。标准说:

    如果 size 为零,则 malloc 的行为是实现定义的。为了 例如,可能会返回一个空指针。或者,一个非空 可以返回指针;但这样的指针不应该 取消引用,并应传递给 free 以避免内存泄漏。

    所以,也许是空指针,也许不是。

    如果是真的,内存中怎么可能存在没有分配内存的东西呢?

    malloc 返回的指针可能指向一块比您请求的内存稍大的内存。例如,如果您要求 1 或 2 个字节,您可能会得到 8 个(甚至 16 个)字节。内存管理器通常只提供一定大小的内存块(为了提高效率),并且可能需要一个最小大小,以便它自己的簿记可以放入 free'd 块中。

    如果它返回一个 1 或 2 字节的超大块,它也可以为 0 字节执行此操作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-06-14
      • 2016-05-24
      • 2012-11-18
      • 2015-12-03
      • 2017-10-26
      • 2018-03-15
      • 1970-01-01
      相关资源
      最近更新 更多