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;
}
来自Linux的输出:
manav@manav-workstation:~$ gcc -Wall mal.c
manav@manav-workstation:~$ ./a.out
0x9363008
(nil)
manav@manav-workstation:~$
malloc(0)
的输出每次都会发生变化。这是标准答案吗?除了学术研究,为什么还会有人对获得这样的指针感兴趣呢?
编辑:
如果malloc(0)
返回伪指针,那么下面的代码是如何工作的:
int main()
{
void *ptr = malloc(0);
printf("%p\n", realloc(ptr, 1024));
return 0;
}
编辑:
下面的代码为每次迭代输出"possible“。为什么它不应该失败呢?
#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;
}
发布于 2010-01-26 04:16:55
其他人回答了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)
(也就是这个case).malloc(0)
中的NULL
返回非NULL
。然后,该调用等同于free(malloc(0))
。在这种情况下,malloc(0)
和realloc(malloc(0), 0)
不是等价的。注意,这里有一个有趣的例子:在第二个例子中,当malloc(0)
在成功时返回非NULL
时,它仍然可能返回NULL
以指示失败。这将产生一个类似于malloc(0)
的调用:realloc(NULL, 0)
,它可能返回NULL
,也可能不返回。
我不确定C99中的省略是一个疏忽,还是意味着在C99中,用于非NULL
ptr
的realloc(ptr, 0)
不等同于free(ptr)
。我刚刚用gcc -std=c99
试过了,上面的相当于free(ptr)
。
编辑:我想我明白你的困惑是什么:
让我们看一下示例代码中的一段代码:
ptr = malloc(0);
if (ptr == realloc(ptr, 1024))
以上内容与malloc(0) == realloc(malloc(0), 1024)
不同。在第二种方法中,malloc()
调用进行了两次,而在第一种方法中,您传递了一个先前分配给realloc()
的指针。
让我们先分析一下第一段代码。假设malloc(0)
在成功时不返回NULL
,则ptr
具有有效值。当您执行realloc(ptr, 1024)
时,realloc()
基本上会给出一个大小为1024的新缓冲区,并且ptr
将变为无效。一致性实现可能会返回与ptr
中已有的地址相同的地址。因此,您的if
条件可能返回true。(但是请注意,在realloc(ptr, 1024)
之后查看ptr
的值可能是未定义的行为。)
现在您要问的问题是:malloc(0) == realloc(malloc(0), 1024)
。在本例中,让我们假设LHS和RHS上的malloc(0)
都返回非NULL
。然后,它们肯定是不同的。此外,LHS上malloc()
的返回值还没有free()
d,所以其他任何malloc()
、calloc()
或realloc()
可能都不会返回该值。这意味着如果你把你的条件写成:
if (malloc(0) == realloc(malloc(0), 1024)
puts("possible");
您不会在输出中看到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;
}
在OS上,我的代码在运行时没有输出任何东西。在Linux上,它打印possible, OK
。
发布于 2010-01-25 20:53:24
malloc(0)
是实现定义的,就C99而言。
来自C99第7.20.3节
通过连续调用calloc、malloc和realloc函数分配的存储的顺序和邻接性在中是不特定的。如果分配成功则返回的指针被适当地对齐,使得它可以被分配给指向任何类型的对象的指针,然后用于在所分配的空间中访问这样的对象或这样的对象的数组(直到空间被显式解除分配)。已分配对象的生命周期从分配到释放。每次这样的分配都应该产生一个指向与任何其他对象不相交的对象的指针。返回的指针指向已分配空间的开始(最低字节地址)。如果无法分配空间,则返回null指针。如果请求的空间大小为零,则行为为-defined空:要么返回null指针,要么行为就好像大小是某个非零值,只是返回的指针不能用于访问对象。
发布于 2010-01-25 20:49:10
在C89中,malloc(0)依赖于实现--我不知道C99是否已经修复了这个问题。在C++中,使用:
char * p = new char[0];
定义良好-您将获得一个有效的非空指针。当然,在不调用未定义行为的情况下,您无法使用指针来访问它所指向的内容。
至于为什么会有这种情况,这对一些算法来说很方便,这意味着你不需要在代码中到处都是零值的测试。
https://stackoverflow.com/questions/2132273
复制相似问题