malloc(0) 返回什么?[重复]

2024-10-14 08:40:00
admin
原创
237
摘要:问题描述:返回什么malloc(0)?答案是否相同realloc(malloc(0),0)?#include<stdio.h> #include<malloc.h> int main() { printf("%p ",...

问题描述:

返回什么malloc(0)

答案是否相同realloc(malloc(0),0)

#include<stdio.h>
#include<malloc.h>
int main()
{
        printf("%p
", malloc(0));
        printf("%p
", realloc(malloc(0), 0));
        return 0;
}

Linux GCC 的输出:

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
", realloc(ptr, 1024));
    return 0;
}

编辑:

以下代码每次迭代都会输出“可能”。为什么它不会失败?

#include<stdio.h>
#include<malloc.h>
int main()
{

        int i;
        void *ptr;
        printf("Testing using BRUTE FORCE
");
        for (i=0; i<65000; i++)
        {
                ptr = malloc(0);
                if (ptr == realloc(ptr, 1024))
                        printf("Iteration %d: possible
", i);
                else
                {
                        printf("Failed for iteration %d
", i);
                        break;
                }
        }
        return 0;
}

解决方案 1:

其他人已经回答了如何malloc(0)工作。我将回答您提出的尚未回答的一个问题(我认为)。问题是关于realloc(malloc(0), 0)

返回什么malloc(0)?答案是否相同realloc(malloc(0),0)

标准是这样说的realloc(ptr, size)

  • 如果ptrNULL,它的行为就像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))

上面的代码与 不同malloc(0) == realloc(malloc(0), 1024)。在第二个代码中,malloc()调用了两次,而在第一个代码中,你将一个先前分配的指针传递给realloc()

让我们首先分析一下第一个代码。假设成功时malloc(0)不返回,则具有有效值。当您执行时,基本上会为您提供一个大小为 1024 的新缓冲区,并且变为无效。符合要求的实现可能会返回与中已有的地址相同的地址。因此,您的条件可能会返回 true。(但请注意,查看after的值可能是未定义的行为。)NULL`ptrrealloc(ptr, 1024)realloc()ptrptrifptr`realloc(ptr, 1024)

现在你要问的问题是:malloc(0) == realloc(malloc(0), 1024)。在这种情况下,我们假设malloc(0)LHS 和 RHS 上的 都返回非NULL。那么,它们肯定是不同的。此外,malloc()LHS 上的 返回值尚未被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 X 上,运行我的代码时没有输出任何内容。在 Linux 上,它会打印possible, OK

解决方案 2:

malloc(0)就 C99 而言是实现定义的。

来自C99 [第 7.20.3 节]

通过连续调用 calloc、malloc 和 realloc 函数分配的存储的顺序和连续性 未指定。如果分配成功,则返回适当对齐的指针,以便可以将其分配给指向任意类型对象的指针,然后用于访问分配空间中的此类对象或此类对象数组(直到明确释放空间)。分配对象的生命周期从分配一直延续到释放。每次这样的分配都会产生一个指向与任何其他对象不相交的对象的指针。返回的指针指向分配空间的起始(最低字节地址)。如果无法分配空间,则返回一个空指针。 如果请求的空间大小为零,则行为是实现定义的:要么返回一个空指针,要么行为就像大小是某个非零值,只是返回的指针不能用于访问对象。

解决方案 3:

在 C89 中,malloc(0) 依赖于实现 - 我不知道 C99 是否已修复此问题。在 C++ 中,使用:

char * p = new char[0];

定义良好 - 您获得一个有效、非空的指针。当然,您不能使用该指针访问其指向的内容,否则会引发未定义的行为。

至于为什么存在这种情况,它对于某些算法来说很方便,并且意味着您不需要在代码中塞满对零值的测试。

解决方案 4:

C99 标准

如果无法分配空间,则返回空指针。如果请求的空间大小为零,则行为由实现定义:要么返回空指针,要么行为就像大小是某个非零值一样,只是返回的指针不得用于访问对象。

解决方案 5:

comp.lang.c常见问题解答如下:

ANSI/ISO 标准规定它可以执行上述任一操作;行为由实现定义(参见问题 11.33)。可移植代码必须注意不要调用 malloc(0),或者为可能返回 null 做好准备。

因此,最好避免使用malloc(0)

解决方案 6:

在您的第一个程序中,还没有人愿意谈论的一点是,realloc长度 0 与 是相同的free

来自 Solaris 手册页:

realloc()函数将 指向的块的大小更改为ptr字节size,并返回指向(可能已移动)块的指针。内容将保持不变,直到新旧大小中较小者。如果ptrNULL,则对于指定的大小,realloc()
其行为类似。如果 为
且 不是空指针,则指向的空间可供应用程序进一步分配,但不会返回给系统。只有在应用程序终止时,内存才会返回给系统。malloc()`size0ptr`

如果人们不知道,这可能会成为一个不好的惊喜的根源(就发生在我身上)。

解决方案 7:

参见 C99,第 7.20.3 节:

如果请求的空间大小为零,则行为由实现定义:要么返回一个空指针,要么行为就好像大小是某个非零值,但返回的指针不能用于访问对象。

calloc()这对于所有三个分配函数(即、malloc()和)都有效realloc()

解决方案 8:

我认为这取决于情况。我检查了 Visual Studio 2005 源代码,并在 _heap_alloc 函数中看到了这一点:

if (size == 0)
    size = 1;

我认为在很多情况下,你可能想要一个有效的指针,即使请求零字节。这是因为这种一致的行为使检查指针变得更容易,因为:如果你有一个非 NULL 指针,那就没问题;如果你有一个 NULL 指针,那么你可能有问题。这就是为什么我认为大多数实现都会返回一个有效的指针,即使请求零字节。

解决方案 9:

如果 malloc(0) 返回虚拟指针,那么以下工作如何进行:

void *ptr = malloc(0);

`printf("%p

", realloc(ptr, 1024));`

我不知道您说的“虚拟指针”是什么意思。如果malloc(0)返回非 NULL,则为ptr指向大小为零的内存块的有效指针。malloc实现以特定于实现的方式保存此信息。 realloc知道(特定于实现的)找出指向ptr大小为零的内存块的方法。

(如何malloc做到reallocfree一点取决于具体实现。一种可能性是分配比请求的多 4 个字节,并将大小存储在内存块之前。在这种情况下,((int *)ptr)[-1]将给出内存块大小,即0。您永远不应该在代码中这样做,它仅供realloc和使用free)。

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2593  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1555  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   32  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   28  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   24  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用