C++ 不正确删除指针碎片内存?
这基本上就是问题所在。如果我有一个指针C++ 不正确删除指针碎片内存?,c++,memory-leaks,C++,Memory Leaks,这基本上就是问题所在。如果我有一个指针int*a=&someIntVar,并且我没有在程序运行过程中删除它,那么在程序终止后它会留在内存中吗?这是数据碎片的情况吗 编辑: 我的错误是使用了一个坏的例子。所以int*a=新的int[100]永远不会被删除,即使它被删除了,答案是删除了指针对象,而不是指针。然而指针也有长度。所以问题是,在Windows或Linux操作系统上,指针之后是否会自动清理?(假设是C++)因为您没有新建这个指针,所以您没有泄漏内存 你要做的是int*a=newint而不是删
int*a=&someIntVar
,并且我没有在程序运行过程中删除它,那么在程序终止后它会留在内存中吗?这是数据碎片的情况吗
编辑:
我的错误是使用了一个坏的例子。所以
int*a=新的int[100]
永远不会被删除,即使它被删除了,答案是删除了指针对象,而不是指针。然而指针也有长度。所以问题是,在Windows或Linux操作系统上,指针之后是否会自动清理?(假设是C++)因为您没有新建
这个指针,所以您没有泄漏内存
你要做的是int*a=newint
而不是删除一个
,那么你就会泄漏一个
根据经验法则,new
s的数量应等于delete
s的数量
当
someIntVar
超出范围时,堆栈将展开,其内存将被释放,a
当然将悬空。否,进程终止时,通常会释放进程分配的所有内存。但是像文件句柄或图形资源(即Win32设备上下文句柄、位图等)这样的东西可能不是这样。关于delete p
的一个令人困惑的事实是,它实际上并没有删除p
,而是删除*p
。也就是说,您不删除指针,而是删除指针对象。无论何时看到delete
,您都应该将其视为delete\u被指向的对象。哦,是的,只有删除你的新的
不正确删除指针碎片内存
否。大量内存分配和释放将导致内存碎片
下面是对内存分配的直观解释(它比这更复杂,我的示例充其量也很幼稚,忽略了很多问题,但它应该能为您提供一些想法)
内存分配通常(至少)分两步进行:
操作系统为应用程序分配内存块
应用程序从可用块中分配内存供自己使用
如果应用程序使用了所有可用内存(或者无法再分配),操作系统将为应用程序分配更多内存。这对应用程序来说是透明的,但需要时间(这就是内存分配缓慢的原因)
当应用程序释放内存时,地址/块被标记为空闲,并将由应用程序在后续分配请求(new/malloc/realloc/etc)中重新使用
内存碎片发生在分配给应用程序的内存块变得碎片化时(一些碎片已分配,一些碎片可用)
例如:
int *a = new int;
int *b = new int;
int *c = new int;
int *d = new int;
int *e = new int;
int *f = new int;
// if the memory blocks for the pointers were allocated contiguously,
// the heap will look like this:
// [ a ][ b ][ c ][ d ][ e ][ f ][ free memory ... ]
// sometime later:
delete b;
delete d;
delete e;
// same memory block will look like this:
// [ a ][free][ c ][free][free][ f ][ free memory ... ]
为了简单起见,假设应用程序以1000字节的可用内存启动)。如果在第一步中您分配了200个int*
(200个不同的变量),那么您将分配200 x 4=800字节,200字节空闲
如果您想分配(在第二步中)newint[100]
more(一个指针,400多个字节),您将没有足够的可用内存,应用程序将不得不从操作系统请求更多。当前块中至少还需要200个字节,或者操作系统中至少需要400个字节的新块)
如果您删除了步骤1中分配的内存,以便为步骤2中的分配腾出空间,则删除的内存至关重要:
- 如果您删除了最后分配的指针-您需要删除最后50个指针(50x4=200)-您将释放200个字节+200个未定位指针(需要400个)正常
- 如果您删除在步骤1中分配的每2个指针(或前50个指针),您将有400个字节可用,但零碎并且没有400个字节的连续内存可用。由于内存碎片,您在步骤2中的分配将失败
我的错误是使用了一个坏的例子。所以int*a=新的int[100]
永远不会被删除,即使它被删除了,答案是删除了指针对象,而不是指针。然而指针也有长度
当你有int*a=newint[100]代码>这里有两个部分:
a
(指针本身)的内存为堆栈上分配的4个字节(假设为32位体系结构)
a
指向的内存是400字节,在堆上分配
当您调用delete[]a时,堆内存将被释放代码>。当*超出范围时,堆栈内存(指针本身)将释放到可用堆栈空间
您只需要关心删除堆内存。堆栈内存由程序本身根据需要释放/重新使用。在您使用的任何操作系统上尝试以下操作:
首先观察进程内存占用情况。在Linux中使用top,在Windows中使用任务管理器李>
分配一个100000的内存,如int*p=newint[100000]李>
观察进程的内存占用情况。它必须至少增加100k*4字节。现在查看为其他进程保留的“空闲”内存李>
让程序运行,不要删除任何内容。执行后,空间被返回到系统——您应该看到其他程序中使用的可用内存现在增加了
作为旁注,不要假设如果您执行delete[]p;在代码的中间,你的100K * 4立即返回系统。这可能是真的,也可能不是真的——例如,Linux有自己的内存管理器来做出这样的决定
Arpan在int*a=newint[100]之后
您正在使用sizeof(a)+sizeof(int[100])
字节内存。在删除一个后,您仍在使用<