malloc(0)的意义是什么?

160
我刚刚看到了这个code:
artist = (char *) malloc(0);

...我在想为什么会有人这样做呢?

请问您需要翻译的内容是:https://dev59.com/r3NA5IYBdhLWcg3wI6V4 - shodanex
18个回答

-1
回答这个问题:实际上没有理由那样做

-2

-2

实际上,这是非常有用的,而且(显然是我个人意见),返回空指针的允许行为是错误的。动态指针不仅对它所指向的内容有用,而且其地址也是唯一的。返回NULL会移除这第二个属性。我经常编写的所有嵌入式malloc都具有此行为。


1
你能举个例子说明这个有什么用吗? - klutt
那你为什么不使用 malloc(1) 呢?这将返回一个唯一的地址(至少在分配对象的生命周期内是唯一的)。 - wovano
PS:我怀疑在“malloc”被“发明”的时候,你的使用情况是否是一个现实的使用情况。 - wovano

-3

运行了valgrind内存检测工具后,这里是分析结果。

==16740== Command: ./malloc0
==16740==
p1 = 0x5204040
==16740==
==16740== HEAP SUMMARY:
==16740==     in use at exit: 0 bytes in 0 blocks
==16740==   total heap usage: 2 allocs, 2 frees, 1,024 bytes allocated
==16740==
==16740== All heap blocks were freed -- no leaks are possible

这是我的示例代码:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
   //int i;
   char *p1;

   p1 = (char *)malloc(0);
   printf("p1 = %p\n", p1);

   free(p1);

   return 0;

}

默认情况下分配了1024字节。如果我增加malloc的大小,分配的字节数将增加1025等等。


2
其实现取决于具体实现。 - Shipof123

-3

使用malloc(0)会返回NULL或一个有效的指针,可以正确地传递给free。虽然它似乎指向的内存是无用的,或者不能被写入或读取,但这并不总是正确的。 :)

int *i = malloc(0);
*i = 100;
printf("%d", *i);

我们预计会在这里出现分段错误,但令人惊讶的是,它打印了100!这是因为当我们第一次调用malloc时,malloc实际上请求了一个巨大的内存块。之后每次调用malloc都使用来自该大块的内存。只有在那个巨大的块用完之后,才会请求新的内存。

使用malloc(0):如果您处于希望后续malloc调用更快的情况下,请调用malloc(0)(除了边缘情况外)。


2
在你的情况下写入 *i 可能不会导致崩溃,但这仍然是未定义行为。小心鼻子恶魔! - John Dvorak
1
是的,那是真的。这取决于具体的实现。我已经在MaxOS X和一些Linux发行版上验证过了。我还没有在其他平台上尝试过。话虽如此,我所描述的概念已经在Brian Kernighan和Dennis Ritchie的书《C程序设计语言》中被描述过。 - Sagar Bhosale
我知道:对于这个问题的评论已经很晚了。但是有时候malloc(0)有一个没有被提到的用途。在那些返回非NULL值的实现中,特别是在DEBUG版本中,它可能会分配比您请求的更多的内存,并给您指向其内部标头之后的指针。如果您在一系列分配之前和之后获取此指针,则可以获得实际内存使用情况的感觉。例如:void* before = malloc(0); ... void* after = malloc(0); long long total = after - before;或类似的操作。 - Jesse Chisholm
我读过Brian Kernighan和Dennis Ritchie的《C程序设计语言》,但我不记得书中有提到malloc(0)。您能告诉我是哪一章吗?如果能提供确切的引用就更好了。 - Андрей Беньковский
但是出人意料的是,这打印了100!哎呀。那么你怎么知道你简单的玩具程序没有以一种在指针无效赋值后立即退出的程序中不明显的方式破坏堆? - Andrew Henle

-7

仅纠正这里的错误印象:

artist = (char *) malloc(0); 永远不会返回 NULL;它与 artist = NULL; 不同。编写一个简单的程序并将 artistNULL 进行比较。if (artist == NULL) 是假的,而 if (artist) 是真的。


1
C标准允许返回NULL,但并不要求这样做。 - klutt

-7
根据Reed Copsey的回答和malloc的man页面,我写了一些示例进行测试。我发现malloc(0)总是会返回一个唯一的值。 看看我的示例:
char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
    puts("Got a null pointer");
else
    puts("Got a valid pointer");

输出将是“获得了有效指针”,这意味着ptr不为空。

2
仅仅因为你总是得到一个有效的指针并不意味着它是有保障的。 - klutt

-9

malloc(0)会返回一个有效的内存地址,其范围取决于被分配内存的指针类型。您可以将值分配给内存区域,但这应该与使用的指针类型相符。您也可以释放已分配的内存。我将用一个例子来解释:

int *p=NULL;
p=(int *)malloc(0);
free(p);

以上代码在Linux机器上的gcc编译器中可以正常工作。如果您有一个32位编译器,那么您可以提供整数范围内的值,即-2147483648到2147483647。字符也是如此。请注意,如果声明的指针类型更改,则值的范围将发生变化,而不管malloc类型转换如何。
unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);

p将会取一个从0到255的char值,因为它被声明为无符号整数。


5
Krellan指出这个答案是错误的:malloc()并不知道类型转换(在C中实际上是完全多余的)。对malloc(0)返回值进行解引用会导致未定义的行为。 - cmaster - reinstate monica

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接