2017-10-13 46 views
3

http://en.cppreference.com/w/c/memory/malloc严格来说,C标准是否要求在malloc之后必须调用free,以及在不满足此要求时规定了什么?

返回的指针必须用免费被解除分配()或realloc()。

http://en.cppreference.com/w/c/memory/calloc

返回的指针必须用免费被解除分配()或realloc()。

严格地说,为什么必须返回指针被释放?

现在我知道POSIX强制内存将在程序终止时被释放,所以在实践中调用malloc并立即终止不会造成任何伤害。但这不是我所问的。

这是硬要求(“必须被解除分配”)存在于C标准,或这是cppreference贡献者的发明,督促程序员不泄漏存储器?如果这样的硬性要求是存在于标准,这是否意味着,按照C标准(POSIX和其他操作系统相关的东西放在一边!),该计划是UB如果malloc返回的指针不是free“d,或做该标准是否定义了未能达到这一要求的后果? (这将是特别有趣,因为这可能意味着标准涉及当程序已经终止会发生什么!)

+2

在某些应用程序中,永不终止的嵌入式应用程序,可能是您调用malloc(),但永远不会释放()以构建将永久生存的内部数据结构,或者直到有人拉动电源线。所以在这种情况下,完成_requirement_来释放分配的内存块是不可能的。 – user1048576

+2

我一直在阅读这个语句,如下所述:“如果你想释放内存,你必须使用'free()'或'realloc ()'”。 –

+1

我认为重点不在于“必须”,而在于“自由”。当该块被释放时,必须使用“free”功能。 –

回答

0

C不要求你给free()分配后的内存。

副作用是内存泄漏。但是你不会看到任何错误或警告。这是您作为程序员修复的工作。

6

当他们说上cppreference.com“返回的指针必须用免费被释放”,但并不意味着作为当务之急,程序员必须做的。它的意思更多的是“当分配的内存被释放时,它必须用free或realloc来完成,因为只有这些函数能够正确执行。”实际规格中没有这样的要求。

1

尽管realloc()free()将是C语言中最自然的释放内存的方式,但在C++中释放内存的最自然的方式是delete。虽然链接的页面描述了C中的行为,但该语言与描述C++行为的页面并行:

成功时,返回指向新分配内存开始处的指针。返回的指针必须用std :: free()或std :: realloc()释放。

我怀疑描述C++文本的预期目的是为了清楚地表明释放存储,包括delete,其他手段不适合于与来自std::mallocstd::calloc接收的存储的使用;即使C没有任何其他预计可行的方法,在描述C时也会出现相同的文本。

+0

我不知道,也许有人会想到使用'munmap'或'sbrk'来代替'free'的负值吗?我觉得这不太可能,尽管 – gaazkam

+0

@gaazkam:实现可能提供其他释放内存的方式,但free和realloc()是标准提供的唯一两个。 – supercat

+0

在malloc之后使用sbrk会导致未定义的行为:http://pubs.opengroup.org/onlinepubs/7908799/xsh/brk。html – mnistic

0

不,绝对没有要求释放任何内存。这样做是为了你自己,允许实现再次使用它来满足未来对malloc的调用。另外,C没有任何关于你的机器/操作系统在C程序之外或终止之后的状态。指定这取决于操作系统或管理它的标准,实际上对于任何多进程操作系统,由malloc和其他类似资源获得的内存都会终止进程。

+0

我同意C标准并不要求你释放内存,但是在你的程序终止后它没有关于你的机器状态的评论与解释这一点无关。 C标准可以指定一个终止而不释放分配的内存的程序会产生一些错误消息或者它在退出时的行为是未定义的等等。也就是说,标准理论上可以强制要求释放记忆而不强加任何终止后要求。 –

+0

@EricPostpischil:第二段更多地解决了“在程序结束时依靠操作系统释放所有内容”“不可移植”的问题这一常见误解。第一段已经提到缺乏对“免费”的要求。 –

0

句子返回的指针必须用free()或realloc()解除分配,C11 standard draft n1570中不存在。

严格地说,标准并没有说对象必须被释放。它甚至没有明确表示内存块需要被freerealloc释放 - 这只是该标准没有提供可用于释放空间的任何其他函数。

但同时,也不能保证他们正在释放的程序退出或者 - 相反,所有的语言开辟了可能性,即通过main进入程序仍然可以通过没有要求free内存泄漏,并仍在运行一个符合实施。标准说,在6.2.4p2

2的对象的生存期是程序执行其间存储是保证被保留用于它部分。一个对象存在,具有一个常数地址,并且在其整个生命周期中保留其最后存储的值.34)如果一个对象被引用到其生命周期之外,则该行为是未定义的。指针的值在其指向的对象(或刚刚过去)达到其生命周期结束时变得不确定。

和在7.22.3p1

一个已分配对象的生存期从分配,直到解除分配延伸。

就是这样。 C标准不关心在之后发生的任何事情程序执行已经终止。这是行为未定义的行为,所以任何可能的行为都是符合标准的。

相关问题