man*_*m-n 53 c linux malloc pointers realloc
什么malloc(0)回报?答案是否相同realloc(malloc(0),0)?
#include<stdio.h>
#include<malloc.h>
int main()
{
printf("%p\n", malloc(0));
printf("%p\n", realloc(malloc(0), 0));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
linux gcc的输出:
manav@manav-workstation:~$ gcc -Wall mal.c
manav@manav-workstation:~$ ./a.out
0x9363008
(nil)
manav@manav-workstation:~$
Run Code Online (Sandbox Code Playgroud)
输出每次都在变化malloc(0).这是标准答案吗?除了学术研究之外,为什么有人会对获得这样的指针感兴趣?
编辑:
如果malloc(0)返回虚拟指针,那么后续工作原理如何:
int main()
{
void *ptr = malloc(0);
printf("%p\n", realloc(ptr, 1024));
return 0;
}
Run Code Online (Sandbox Code Playgroud)
编辑:
以下代码为每次迭代输出"可能".为什么不失败?
#include<stdio.h>
#include<malloc.h>
int main()
{
int i;
void *ptr;
printf("Testing using BRUTE FORCE\n");
for (i=0; i<65000; i++)
{
ptr = malloc(0);
if (ptr == realloc(ptr, 1024))
printf("Iteration %d: possible\n", i);
else
{
printf("Failed for iteration %d\n", i);
break;
}
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Alo*_*hal 44
其他人已经回答了如何malloc(0)运作 我会回答你提出的一个尚未回答的问题(我认为).问题是realloc(malloc(0), 0):
什么
malloc(0)回报?答案是否相同realloc(malloc(0),0)?
该标准说明了这一点realloc(ptr, size):
ptr是NULL,它表现得像malloc(size),ptr不是NULL),它将旧对象指针解除分配给ptr并返回指向新分配缓冲区的指针.但如果size是0,C89说效果相当于free(ptr).有趣的是,我无法在C99草案(n1256或n1336)中找到该声明.在C89中,在这种情况下返回的唯一明智的价值是NULL.所以,有两种情况:
malloc(0)返回NULL实现.然后你的realloc()电话相当于realloc(NULL, 0).这相当于malloc(0)从上面(NULL在这种情况下).malloc(0)返回非NULL.然后,呼叫相当于free(malloc(0)).在这种情况下,malloc(0)并且realloc(malloc(0), 0)是不等价的.请注意,这里有一个有趣的案例:在第二种情况下,当成功malloc(0)返回非NULL成功时,它仍然可以返回NULL以指示失败.这将导致一个类似于的调用realloc(NULL, 0),这相当于malloc(0),可能会或可能不会返回NULL.
我不确定C99中的遗漏是否是一种疏忽,或者它是否意味着在C99中,realloc(ptr, 0)对于非NULL ptr等同于free(ptr).我刚试过这个gcc -std=c99,上面相当于free(ptr).
编辑:我想我明白你的困惑是什么:
让我们看一下示例代码中的代码段:
ptr = malloc(0);
if (ptr == realloc(ptr, 1024))
Run Code Online (Sandbox Code Playgroud)
以上不一样malloc(0) == realloc(malloc(0), 1024).在第二个中,malloc()调用是两次,而在第一个中,您将先前分配的指针传递给realloc().
让我们先分析第一个代码.假设成功后malloc(0)没有返回NULL,ptr则具有有效值.当你这样做时realloc(ptr, 1024),realloc()基本上会给你一个大小为1024的新缓冲区,并且ptr变得无效.符合要求的实现可以返回与已经存在的地址相同的地址ptr.所以,你的if病情可能会恢复正常.(注意,但是,查看ptrafter 的值realloc(ptr, 1024)可能是未定义的行为.)
现在你问的问题:malloc(0) == realloc(malloc(0), 1024).在这种情况下,让我们假设malloc(0)LHS和RHS都返回非NULL.然后,他们保证是不同的.此外,从返回值malloc()的LHS尚未free()ð还,所以任何其他的malloc(),calloc()或realloc()可能不会返回值.这意味着如果您将条件写为:
if (malloc(0) == realloc(malloc(0), 1024)
puts("possible");
Run Code Online (Sandbox Code Playgroud)
你不会看到possible在输出(除非双方malloc()和realloc()失败并返回NULL).
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
void *p1;
void *p2;
p1 = malloc(0);
p2 = realloc(p1, 1024);
if (p1 == p2)
puts("possible, OK");
/* Ignore the memory leaks */
if (malloc(0) == realloc(malloc(0), 1024))
puts("shouldn't happen, something is wrong");
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在OS X上,当我运行它时,我的代码没有输出任何内容.在Linux上,它打印possible, OK.
Pra*_*rav 34
malloc(0)是关于C99的实现定义.
来自C99 [第7.20.3节]
通过连续调用calloc,malloc和realloc函数分配的存储的顺序和连续性 是未指定的.如果分配成功,则返回的指针被适当地对齐,以便可以将其指定给指向任何类型对象的指针,然后用于在分配的空间中访问此类对象或此类对象的数组(直到空间被显式释放) .分配对象的生命周期从分配延伸到解除分配.每个这样的分配都应该产生一个指向与任何其他对象不相交的对象的指针.返回的指针指向分配空间的开始(最低字节地址).如果无法分配空间,则返回空指针. 如果请求的空间大小为零,则行为是实现定义的:返回空指针,或者行为就像大小是非零值一样,除了返回的指针不应用于访问对象.
小智 15
在C89中,malloc(0)依赖于实现 - 我不知道C99是否已修复此问题.在C++中,使用:
char * p = new char[0];
Run Code Online (Sandbox Code Playgroud)
定义得很好 - 你得到一个有效的非空指针.当然,您无法使用指针访问它指向的内容而不调用未定义的行为.
至于为什么存在这种情况,对于某些算法来说很方便,并且意味着您不需要使用零值测试来丢弃代码.
C99标准
如果无法分配空间,则返回nullpointer.如果请求的空间大小为零,则行为是实现定义的:返回空指针,或者行为就像大小是非零值一样,但返回的指针不应用于访问对象.
ANSI/ISO标准说它可以做任何一种; 行为是实现定义的(见问题11.33).可移植代码必须注意不要调用malloc(0),或者为空返回的可能性做好准备.
所以,最好避免使用malloc(0).
| 归档时间: |
|
| 查看次数: |
32556 次 |
| 最近记录: |