这已成为困扰我多年的事情.
我们都在学校(至少,我是)教过你必须释放每个分配的指针.不过,我有点好奇,关于不释放内存的实际成本.在一些明显的情况下,就像在malloc循环内部或线程执行的一部分中调用时一样,释放是非常重要的,因此没有内存泄漏.但请考虑以下两个例子:
首先,如果我的代码是这样的:
int main()
{
char *a = malloc(1024);
/* Do some arbitrary stuff with 'a' (no alloc functions) */
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这里真正的结果是什么?我的想法是,进程死了,然后堆空间无论如何都没有了,因此错过调用没有任何害处free(但是,我确实认识到无论如何都要将它关闭,可维护性和良好实践的重要性).我对这个想法是对的吗?
其次,假设我的程序有点像shell.用户可以声明类似的变量,aaa = 123并将其存储在某些动态数据结构中供以后使用.很明显,你可以使用一些解决方案来调用一些*alloc函数(hashmap,链表,类似的东西).对于这种程序,在调用之后永远自由是没有意义的,malloc因为这些变量必须在程序执行期间始终存在,并且没有好的方法(我可以看到)用静态分配的空间来实现它.拥有一堆已分配但仅作为流程结束的一部分释放的内存,这是不好的设计吗?如果是这样,有什么替代方案?
我创建的结构:
struct VideoSample
{
const unsigned char * buffer;
int len;
};
VideoSample * newVideoSample = new VideoSample;
newVideoSample->buffer = buf;
newVideoSample->len = size;
//...
Run Code Online (Sandbox Code Playgroud)
现在怎么删除呢?
我认为在重新分配动态分配的指针时,我们都理解删除的必要性,以防止内存泄漏.但是,我很好奇,C++在多大程度上强制要求使用delete?例如,采取以下计划
int main()
{
int* arr = new int[5];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
虽然所有意图和目的都没有发生泄漏(因为你的程序结束了,操作系统会在它返回后清理所有内存),但标准是否还需要 - 或建议 - 在这种情况下使用delete [] ?如果没有,还有其他原因你会在这里删除[]吗?
在C++中,当您在堆上创建一个新变量时,如下所示:
int* a = new int;
Run Code Online (Sandbox Code Playgroud)
你可以告诉C++使用delete这样回收内存:
delete a;
Run Code Online (Sandbox Code Playgroud)
但是,当程序关闭时,是否会自动释放分配了新内存的内存?
这可能是一个有点愚蠢的问题 - 我应该delete在程序结束时调用巨大的地图/集合吗?
假设整个程序都需要map/set(delete返回前的最后一行),它的大小非常大(> 4GB).这个delete电话花了很长时间,从我的角度来看没有任何价值(内存不能早点发布),我错了吗?如果是这样,为什么?
我知道,如果我没有释放分配的内存删除/免费我最终会有内存泄漏.我的问题是:如果我的程序被终止,操作系统是否会为我释放内存,即使我没有?
我知道清理是件好事.我也理解操作系统内部,所以如果我知道我的进程正在终止,那么它的内存将被释放.但我想提出不同的观点.我觉得在退出时释放内存是相当不错的想法.
例如,我可能已经分配了当前换出的大内存,如果我在退出时释放它,则需要将其带到RAM,然后释放它.如果我不这样做,退出时只需在一张桌子上标记为免费.
总的来说,操作系统已经发生了很大的变化(基础知识保持不变),我理解这个问题可以被认为是A_VERY_PLATFORM_DEPENDENT,但是从今天的应用程序开发人员的角度来看,他要么陷入某些框架,要么被困在某个框架中,或者是daredevil编码器,正在研究原始技术作为COM,非常依赖,我会称之为VERY_CONTROLLED_ENVIRONMENT.
对于TL;DR:在现代操作系统上,我认为我不应该在退出时执行清理.如果你认为我错了,为什么?
PS:我不是在谈论RTOS,我的意思是受控环境意味着Windows,Linux和我从未意味着设备驱动程序开发或操作系统开发.