假设我有以下C代码:
int main () {
int *p = malloc(10 * sizeof *p);
*p = 42;
return 0; //Exiting without freeing the allocated memory
}
Run Code Online (Sandbox Code Playgroud)
当我编译并执行该C程序时,即在内存中分配一些空间之后,在我退出应用程序并且进程终止后,我分配的内存是否仍会被分配(即基本上占用空间)?
main例如,在我的C++ 函数中,如果我有一个指向使用堆内存的变量的指针(而不是堆栈内存) - 在我的应用程序退出后会自动解除分配吗?我会这么认为.
即便如此,即使您认为永远不会在退出时自动释放内存的情况下使用堆分配,也总是删除堆分配是一种好习惯吗?
例如,这样做有什么意义吗?
int main(...)
{
A* a = new A();
a->DoSomething();
delete a;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我想也许以防我重构(或其他人重构)代码并将其放在应用程序的其他地方,这delete真的是必要的.
除了Brian R. Bondy(其中特别谈到C++中的含义)的答案之外,Paul Tomblin 对C特定问题也有一个很好的答案,该问题也讨论了C++析构函数.
这是我的问题:调用free或delete是否会将内存释放回"system".我的意思是,系统是否会减少流程的数据段?
让我们考虑Linux上的内存分配器,即ptmalloc.
据我所知(如果我错了请纠正我),ptmalloc维护一个免费的内存块列表,当内存分配请求到来时,它会尝试从这个空闲列表中分配一个内存块(我知道,分配器很多)比这更复杂,但我只是简单地说它)但是,它失败了,它使用say sbrk或brk系统调用从系统获取内存.当一个内存被释放时,该块被放置在空闲列表中.
现在考虑这种情况,在峰值负载时,已经在堆上分配了许多对象.现在当负载减少时,对象是免费的.所以我的问题是:一旦对象被free'd将分配器做一些计算,以发现是否应该保持这个对象在免费的列表或取决于空闲列表的当前大小可能决定给内存回系统即使用sbrk或brk减少进程的数据段.
glibc的文档告诉我,如果分配请求比页面大小大得多,它将使用mmap分配,并且一旦被释放就会直接释放回系统.凉.但是让我说我从来没有要求分配大于50字节的大小,并且我在系统的峰值负载上询问了很多这样的50字节对象.那又怎样?
据我所知(指正请),使用malloc分配的内存将永远不会被释放回过,直到进程结束即分配器只会保持在空闲列表,如果我释放它的系统.但是,这是困扰我的问题是,那么,如果我用一个工具来查看我的进程的内存使用情况(我在Linux上使用PMAP,你们怎么使用呢?),它应该始终显示在高峰负荷使用的内存(因为内存永远不会返回给系统,除非使用mmap分配)?那个进程使用的内存永远不会减少(堆栈内存除外)?是吗 ?
我知道我错过了什么,所以请详细说明这一切.
专家,请清楚我的相关概念.我会很感激.我希望我能够解释我的问题.
如果我在我的C程序中使用分配内存,malloc现在我想退出,我是否必须释放分配的内存,或者我可以假设,因为我的整个程序终止,它将被操作系统释放?
我在Linux环境中运行.
因错误而退出程序时,我应该释放所有的mallocated内存吗?
something = (char**) malloc (x * sizeof(char*));
for (i = 0; i < x; i++)
something[i] = (char*) malloc (y + 1);
...
if (anything == NULL) {
printf("Your input is wrong!");
// should I free memory of every mallocated entity now?
exit(1);
}
else {
// work with mallocated entities
...
free(something); // it must be here
system("pause);
}
Run Code Online (Sandbox Code Playgroud) 说我有以下程序
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int * i;
if ((i = malloc(sizeof(int) * 100)) == NULL) {
printf("EROOR: unable to allocate memory \n");
return -1;
}
/* memory is allocated successfully */
/* memory is not free'ed but program terminates */
// free(i);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
上面的程序调用malloc分配一些内存而不调用free取消分配它.程序终止而不取消分配内存.
Valgrind清楚地发现内存泄漏.
<snap>
==14209== HEAP SUMMARY:
==14209== in use at exit: 400 bytes in 1 blocks
==14209== total heap usage: 1 allocs, 0 frees, 400 bytes allocated …Run Code Online (Sandbox Code Playgroud) 比方说,举个例子:
int main()
{
char* test = new char[50000];
return 0;
}
Run Code Online (Sandbox Code Playgroud)
程序完成后分配的内存会发生什么变化?是否立即获得其他应用程序的释放?或者也许过了一段时间?或许它永远丢失在系统中?或者它是否被交换到磁盘永远不会返回到RAM?或者也许完全不同的东西?
我想知道主要3操作系统会发生什么:Windows(XP及以上,如果有任何差异),Linux,Mac OS X.
假设我将一些内存malloc到某些指针但在程序退出之前不要释放它们.这个内存是否会在退出时自动释放,或者内存泄漏会继续存在,直到我重新启动计算机?
这是我的问题:运行一套程序后,free告诉我执行后大约有1 GB的可用内存减少。经过一番搜索后,我发现这样:当您在 malloc 之后不释放时,真正会发生什么(据我所知),这清楚地表明丢失的内存释放不应该是问题......(这是正确的吗?)
top不显示任何使用大量内存的进程。
我如何找出内存“发生了什么” ,即哪个程序分配了它以及为什么程序执行后它不空闲?
从哪里free收集其信息?
(我正在运行最新的 Ubuntu 版本)
当我有一个应该重复用作参数realloc并保存其返回值的指针时,我知道realloc如果无法进行分配,则不会触及旧对象,返回NULL. 我是否还应该担心以下结构中的旧对象:
int *p = (int *)malloc(sizeof(int *));
if (p = (int *)realloc(p, 2 * sizeof(int *)))
etc...
Run Code Online (Sandbox Code Playgroud)
现在,如果realloc成功了,我需要free(p)在完成后进行。当realloc失败时,我已指定它返回NULL并且p不free(p)执行任何操作(因为它是 a free(NULL))。同时(根据标准)旧对象不会被释放。p那么我是否应该有一个(例如)的副本int *last_p = p;来跟踪旧对象,以便free(last_p)在realloc失败时可以?