C-如果``malloc(0)`返回一个非挂钩指针,我可以将其传递给`free'



我一直在阅读有关malloc在请求零尺寸块时的行为的讨论。

我了解malloc(0)的行为是实现定义的,应该返回null指针,是我不应该访问的非弹药指针。(这是有道理的,因为不能保证它指向任何可用的内存。(

但是,如果a获得这样的不可访问的非挂钩指针,我是否允许以通常的方式将其传递给free?还是那是非法的,因为我从malloc(0)获得的指针可能无法指向实际分配的内存块?

具体而言,以下代码具有明确的行为:

#include <stdio.h>
#include <stdlib.h>
int main() {
    int* x = (int*) malloc(0);
    if (x == NULL) {
        printf("Got NULLn");
        return 0;
    } else {
        printf("Got nonnull %pn", x);
    }
    free(x); // is calling `free` here okay?
}

C99标准(实际上是WG14/N1124。委员会草案 - 2005年5月6日。ISO/IEC 9899:TC2(关于malloc()

指针返回点开始(最低字节 分配空间的地址(。如果无法分配空间,则无效指针是 回。如果所请求的空间的大小为零,则该行为是定义的: 返回了无效指针,或者行为是大小是某些大小 非零值,除了返回的指针不得用于访问对象

和关于 free()

否则,如果 该参数不匹配calloc,malloc或realloc函数返回的指针,或者如果空间已被呼叫呼叫免费或realloc,则行为是未定义的。

IEEE STD 1003.1-2008(POSIX(,2016年版有关free()

free((函数应导致PTR指向的空间为 交易;也就是说,可用于进一步分配。如果是PTR 无效指针,不会采取任何行动。否则,如果论点确实 不匹配POSIX的函数返回的指针。1-2008 这将记忆好像通过malloc((或空间已经 由free((或realloc((的呼叫所划分的行为是 未定义。

所以,无论*alloc()返回,您都可以传递给free()

对于malloc()的当前实现:

freeBSD使用

的贡献的jemalloc
void *
je_malloc(size_t size)
{
    void *ret;
    size_t usize JEMALLOC_CC_SILENCE_INIT(0);
    if (size == 0)
        size = 1;
    [...]

苹果的libmalloc确实

void *
szone_memalign(szone_t *szone, size_t alignment, size_t size)
{
    if (size == 0) {
        size = 1; // Ensures we'll return an aligned free()-able pointer
    [...]

GLIBC还更改了所需的大小;它正在使用对此宏的调用,其中所需的大小是字节中的参数,以使大小与特定边界对齐或最小分配大小:

#define request2size(req)                                       
    (((req) + SIZE_SZ + MALLOC_ALIGN_MASK < MINSIZE)  ?         
    MINSIZE :                                                   
    ((req) + SIZE_SZ + MALLOC_ALIGN_MASK) & ~MALLOC_ALIGN_MASK)

是的,实际上,您必须这样做才能避免可能的内存泄漏。

Malloc系统通常在指针前的空间中返回一个隐藏的控制块,并带有分配尺寸之类的信息。如果分配大小为零,则此块仍然存在并占据内存,如果Malloc返回非零件。

相关内容

  • 没有找到相关文章

最新更新