artist = NULL;
malloc(0)
返回一个有效指针,那么malloc()
返回NULL
就意味着"失败",而0
也不再是特殊情况,这更加一致。 - Alok Singhalmalloc
在无法获得内存时的情况是实现定义的,因此一种实现方式是将大小为0的分配始终定义为不可满足(ENOMEM
)。现在malloc(0)
返回0(并且errno == ENOMEM
)是一致的。 :-) - R.. GitHub STOP HELPING ICEmalloc(0)
返回的指针使用realloc
吗?你可以对(char*)NULL
使用realloc
吗? - Braden Bestmalloc(0)的行为取决于实现。库可以返回NULL或具有常规的malloc行为,但不会分配任何内存。无论它做什么,都必须在某个地方进行记录。
通常情况下,它会返回一个有效且唯一的指针,但不应对其进行解引用操作。还要注意,即使它实际上没有分配任何内容,也可能会消耗内存。
可以realloc非空的malloc(0)指针。
然而,直接使用malloc(0)并没有多少用处。它通常用于动态分配大小为零的情况,并且您并不关心是否验证了它。
malloc()
必须在某个地方保留“管理信息”(例如分配的块的大小和其他辅助数据)。因此,如果malloc(0)
不返回NULL
,它将使用内存存储该信息,如果没有通过free()
释放,就会构成内存泄漏。 - Alok Singhalmalloc()
会返回的唯一指针,或者返回NULL
。 - Alok Singhalmalloc()
的手册页面表示:
如果大小为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。 - Todd LehmanNULL
或唯一指针”,而是“一个空指针或指向分配空间的指针”。因此,没有“唯一”的要求。但是,返回一个非唯一特殊值可能会破坏依赖于唯一值的代码。也许这是一个适合在Stack Overflow上探讨的角落案例问题。 - chux - Reinstate Monica为什么你不应该这样做...
由于malloc的返回值是实现相关的,你可能得到一个空指针或其他地址。如果错误处理代码没有检查大小和返回值,就会出现堆缓冲区溢出,导致稳定性问题(崩溃)或更严重的安全问题。
考虑以下示例,在返回的地址上进一步访问内存,如果大小为零且实现返回一个非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)
对我来说没有任何意义,除非代码依赖于特定实现的行为。如果代码需要可移植性,那么必须考虑到从malloc(0)
返回NULL并不是失败。那么为什么不把NULL分配给artist
呢?因为这是一个有效的成功结果,而且代码更少,不会让维护程序员花时间去理解。
malloc(SOME_CONSTANT_THAT_MIGHT_BE_ZERO)
或malloc(some_variable_which_might_be_zero)
可能有它们的用途,尽管您必须特别小心,以免将NULL返回视为失败,如果值为0,则0大小应该是可以接受的。
realloc
的东西:
realloc(foo, size);
。当您将非NULL指针和大小为零的值传递给realloc时,realloc的行为就像您调用了free(...)。realloc(foo, size);
。当您传入一个空指针并且大小为非零时,realloc的行为就像您调用了malloc(...)。在Windows系统中:
void *p = malloc(0);
会在本地堆上分配一个零长度的缓冲区。返回的指针是一个有效的堆指针。malloc
最终使用默认的C运行时堆调用HeapAlloc
,然后调用RtlAllocateHeap
等函数。free(p);
使用HeapFree
来释放堆上的0长度缓冲区。不释放会导致内存泄漏。编写代码的人可能希望您将malloc(0)
视为一个空初始化数组,可以向其中添加值(使用realloc()
)。虽然这样做无论malloc(0)
返回NULL
还是实际指针都可以工作, 但它会引起误解:
如果没有实现意识,您将无法确定malloc(0)
返回的潜在NULL
的含义。它可能意味着您的内存已用完,但也可能意味着实现决定为大小为0的分配返回该值。即使这对您的代码无关紧要,它也可能引起一些疑问。
这意味着malloc(0)
是尝试编写更易读的代码的尝试。但是,由于它涉及特定于实现的行为并在此过程中丢失信息,因此很可能会导致混淆。除非您明确需要实现特定行为的结果,否则不要使用它。
malloc(0)
,如何可移植地处理检查失败呢?如果您根本不使用malloc(0)
,则malloc()
返回NULL
失去了作为错误条件的所有特殊含义。这正好与“高级语言程序员”的情况相反 - 您的代码丢失了信息,现在必须编写额外的代码来弥补这一点。 - Andrew Henlemalloc(0)
是不符合惯用法的。我不确定“转移责任”的意义在哪里;使用malloc(0)
的结果并没有更好地分配一个正确的值,就像分配NULL
一样(更少因为分配的值对malloc(0)
是实现定义的),并且当然它把检查分配错误的责任转移到可能稍后调用realloc
。我没有看到任何关于这个问题的“更高级别”的东西;它似乎很混乱。 - ad absurdum