Answers:
根据规范,malloc(0)将返回“可以成功传递给free()的空指针或唯一指针”。
基本上,这让您什么都没分配,但是仍然不用担心将“ artist”变量传递给对free()的调用。出于实际目的,它与执行操作几乎相同:
artist = NULL;
C标准(C17 7.22.3 / 1)指出:
如果请求的空间大小为零,则行为是由实现定义的:返回空指针,或者行为类似于该大小为某个非零值,不同之处在于返回的指针不得用于访问对象。
因此,malloc(0)
可以返回NULL
或不能取消引用的有效指针。无论哪种情况,调用free()
它都是完全有效的。
我真的认为malloc(0)
没有什么用,除非在malloc(n)
例如循环中被调用的情况下,以及n
可能为零)。
通过查看链接中的代码,我相信作者有两个误解:
malloc(0)
始终返回有效的指针,并且free(0)
不好。因此,他确保artist
和其他变量始终在其中具有某些“有效”值。评论内容如下:// these must always point at malloc'd data
。
malloc(0)
返回有效指针,则malloc()
返回NULL
始终表示“失败”,并且0
不再是特殊情况,这更加一致。
malloc
无法获取内存的情况是由实现定义的,因此实现可以简单地定义size-0分配总是不满足(ENOMEM
),而现在malloc(0)
返回0(带有errno==ENOMEM
)是一致的。:-)
realloc
返回一个指针malloc(0)
吗?可以realloc((char*)NULL)
吗
malloc(0)行为是特定于实现的。该库可以返回NULL或具有常规的malloc行为,而不分配任何内存。无论做什么,都必须在某处记录下来。
通常,它返回有效且唯一的指针,但不应取消引用。还要注意,即使它实际上没有分配任何东西,它也可能消耗内存。
可以重新分配非null的malloc(0)指针。
逐字使用malloc(0)并没有多大用处。当动态分配为零字节且您不希望验证它时,通常使用它。
malloc()
必须在某处保留“客房整理信息”(例如,分配的块的大小以及其他辅助数据)。因此,如果malloc(0)
不返回NULL
,它将使用内存来存储该信息,如果不返回free()
d,将构成内存泄漏。
malloc()
会返回)或return NULL
。
malloc(0)
。但是,在与标准C库完全相同的实现中,realloc(ptr, 0)
释放ptr
并返回NULL。
这里有很多正确的答案,所以这里有一些困难的事实。的手册页malloc()
说:
如果size为0,则malloc()返回NULL或唯一的指针值,该值以后可以成功传递给free()。
这意味着,绝对不能保证的结果malloc(0)
是唯一的或不是NULL。唯一的保证是由的定义free()
再次提供的,这是手册页所说的内容:
如果ptr为NULL,则不执行任何操作。
因此,无论malloc(0)
返回什么,它都可以安全地传递给free()
。但是NULL
指针也可以。
因此,写作 artist = malloc(0);
绝不比写作好 artist = NULL;
malloc(0)
可以返回0x1,并且free()
可以像对0x0一样进行特殊情况下的0x1检查。
NULL
或唯一指针”。。而不是“要么一个空指针或分配空间”有没有独特的要求OTOH,返回非唯一的特殊值可能会破坏代码的唯一值计数因此,也许一个角落情况的问题。
man
还可以记录* nix中使用的实现定义的形式。在这种情况下,它不是,但是仍然不是通用C的规范来源
为什么你不应该这样做...
由于malloc的返回值取决于实现,因此您可能会获得NULL指针或其他地址。如果错误处理代码无法同时检查大小和返回值,则最终可能导致堆缓冲区溢出,从而导致稳定性问题(崩溃)甚至更严重的安全问题。
考虑一下这个示例,其中进一步通过返回的地址访问内存将破坏堆,如果大小为零,并且实现返回一个非NULL值。
size_t size;
/* Initialize size, possibly by user-controlled input */
int *list = (int *)malloc(size);
if (list == NULL) {
/* Handle allocation error */
}
else {
/* Continue processing list */
}
请参阅CERT编码标准中的此“安全编码”页面,在该页面中,我以上面的示例作为进一步阅读。
malloc(0)将返回NULL或可以正确传递给free的有效指针。尽管看起来它指向的内存是无用的或无法写入或读取的,但这并不总是正确的。:)
int *i = malloc(0);
*i = 100;
printf("%d", *i);
我们期望在这里出现分段错误,但是令人惊讶的是,它会打印100!这是因为当我们第一次调用malloc时,malloc实际上需要大量内存。之后,每次对malloc的调用都使用该大块中的内存。只有在那巨大的块结束之后,才需要新的内存。
使用malloc(0):如果您希望后续的malloc调用更快,则调用malloc(0)应该可以为您做到(边缘情况除外)。
*i
在您的情况下,写入可能不会崩溃,但是仍然是未定义的行为。当心鼻恶魔!
malloc(0)
没有提到它的用途。在那些返回非NULL值的实现上,尤其是在DEBUG构建中,它可能分配的容量超出了您的要求,并且为您提供了指向其内部标头的指针。这可以让你得到一个感觉实际内存使用情况,如果你在这之前和之后的一系列分配得到。例如:void* before = malloc(0); ... void* after = malloc(0); long long total = after - before;
或类似的东西。
malloc(0)
。您能说一下您指的是哪一章吗?提供准确的报价也很好。
它实际上非常有用,并且(显然是恕我直言)打破了返回NULL指针的允许行为。动态指针不仅对它指向的内容有用,而且它的地址是唯一的。返回NULL将删除该第二个属性。我编程的所有嵌入式malloc(实际上很多时候)都具有此行为。
不确定,根据我发现的一些随机malloc源代码,输入0会导致返回值NULL。因此,这是一种将艺术家指针设置为NULL的疯狂方式。
http://www.raspberryginger.com/jbailey/minix/html/lib_2ansi_2malloc_8c-source.html
这是使用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,依此类推。
根据Reed Copsey的回答和malloc的手册页,我编写了一些示例进行测试。而且我发现malloc(0)总是会赋予它唯一的值。看我的例子:
char *ptr;
if( (ptr = (char *) malloc(0)) == NULL )
puts("Got a null pointer");
else
puts("Got a valid pointer");
输出将是“获得有效的指针”,这意味着ptr
不为null。
malloc(0)
将返回一个有效的内存地址,其范围将取决于分配给内存的指针的类型。另外,您可以为存储区分配值,但是该值应在所使用的指针类型的范围内。您还可以释放分配的内存。我将用一个示例对此进行解释:
int *p=NULL;
p=(int *)malloc(0);
free(p);
上面的代码gcc
在Linux机器上的编译器中可以正常工作。如果您有32位编译器,则可以提供整数范围内的值,即-2147483648至2147483647。同样适用于字符。请注意,如果声明的指针类型改变,则值的范围将改变,而与malloc
类型转换无关,即
unsigned char *p=NULL;
p =(char *)malloc(0);
free(p);
p
因为它被声明为unsigned int,所以它将采用从0到255之间的char值。
malloc()
不了解任何有关强制转换的信息(实际上在C语言中完全多余)。取消引用的返回值malloc(0)
将调用未定义的行为。
此处只是为了纠正错误的印象:
artist = (char *) malloc(0);
永远不会回来NULL
; 与并不相同artist = NULL;
。编写一个简单的程序,比较artist
有NULL
。if (artist == NULL)
是错误的,if (artist)
是真实的。