记忆释放查询

时间:2010-03-03 16:00:07

标签: c++ memory-management pointers

另外感谢Daniel Newby以回答我的内存使用问题(以及Martin York对其进行更多解释)。这绝对是我一直在寻找的答案,但我的其他问题更多都得到了其他人的回答。

谢谢大家

清除所有疑虑。非常高兴看到我希望它们运行的​​方式。

我遇到了一些我不太确定的事情。

在我的计划中,我没有使用malloc()free()。我正在使用new制作我的课程实例我已经确保每个人在destructor'时运行它delete,但是,有没有free()调用甚至将其指针(针对全局范围或其他类中的内容)设置为NULL0

我的意思是“我确定了”,并不是我称之为每个析构函数。我只使用delete来调用析构函数来运行,但是我每次创建一个对象时都会增加1,并且每次运行析构函数时都会增加。这就是我如何确保我创建的对象数量等于被调用的析构函数的数量。

我是否应该使用malloc()free()?我应该NULL指向我仍然想要存在的事物吗?

第二个问题是,当我查看我的任务管理器时,为什么我的进程永远不会“丢弃”内存?它曾经永远不会停止获取,然后我开始deleting一切正常。或者我想。

free()delete不会使内存使用量下降吗?

我应该通过链接列表了解mallocfree内存的哪些做法?

6 个答案:

答案 0 :(得分:2)

您应该将deletenewfreemalloc一起使用。 delete将调用类的析构函数,因此您不必显式调用它。析构函数的目的是释放类可能具有的资源,delete也将释放内存。

您应该通过placement new 初始化对象时,唯一应该明确使用析构函数的时间。您应该将自己置于编译器生成的代码释放资源的位置 - 阅读本文关于C ++习语:resource acquisition is initialization

同样将类的指针设置为null什么都不做,后台没有垃圾收集器清理你的内存。如果你没有在C ++中释放动态内存,它将被“泄露”内存 - 也就是说,没有内存链接,在进程退出之前永远不会回收它。

p.s。,再次不要混合内存分配函数对。

edt:不实现链接列表,请使用标准模板库提供的容器。如果您觉得需要更好的性能,请使用boost中的intrusive containers

答案 1 :(得分:2)

在C ++程序中很少有理由使用malloc()free()。坚持使用newdelete。请注意,与具有垃圾收集的语言不同,在C ++中将指针设置为NULL或0与释放内存无关。

答案 2 :(得分:0)

你应该优先使用new和delete来取消malloc()/ calloc()/ realloc()和free()。​​

如果您要创建链接列表,则应使用std::list.此外,请查看std::vector

就应用程序的明显内存使用情况而言:在应用程序退出之前,内存很可能不会返回给系统。

答案 3 :(得分:0)

  1. new和delete可以或多或少地被认为是malloc和free的C ++版本。所以坚持在一对或另一对中,即如果指针是用new创建的,它应该与delete一起释放,这确保了你提到的析构函数调用。 malloc / free对不支持C ++,只是分配和释放一块没有附加构造函数/析构函数语义的内存块。

  2. 是的,我认为在将指针释放或删除时将指针设置为NULL或零是一种好方法。在调试过程中,我有时会将它们设置为像0xdeadbeef这样的特性,以便它们脱颖而出。

  3. 操作系统“内存使用率”可能反映了进程堆的整个大小,而不是内存管理器对内存分配量的想法。当分配器发现它没有足够的堆空间时,它会增加堆,这将反映在您正在查看的“内存使用情况”中。从理论上讲,可以在内存释放时相应地缩小堆,但这并不总是会发生。因此,您可能只会看到内存使用量增长,并且永远不会缩小。

答案 4 :(得分:0)

“我应该使用malloc()和free()吗?”

不,在大多数情况下。坚持使用一种形式的内存管理。尝试使用两者意味着你将不可避免地搞砸并删除一个malloc()ed项,或者free()一个新项目,给出一个微妙的bug。坚持使用一种形式,并提前修复这些错误。

“不会释放()或删除会使内存使用率下降吗?”

操作系统在页面中分配内存,通常为4 kiB。只要页面的单个字节仍在使用中,它就不会返回到操作系统。您可能正在分配许多小项目,但不会释放所有这些项目。 (有一些方法可以帮助自定义新/删除,但它们通常不值得付出努力。)

答案 5 :(得分:0)

  

在我的程序中,我没有使用malloc()或free()。我正在使用new创建我的类的实例,并确保每个实例都在删除时运行它的析构函数,

这太吓人了。你不应该让任何东西运行它的析构函数。它被分配(新)它被销毁(删除)构造函数在new上自动运行,析构函数在删除时自动运行。

  

但是,没有free()调用甚至将它们的指针(对于全局作用域或其他类中的内容)设置为NULL或0。

没有必要在C ++代码中使用malloc / free(在某些情况下,您使用的是需要malloced内存的C库,但它们是明确记录的,很少)。

从技术上讲,删除它后不需要将指针设置为NULL 在删除变量后,变量超出范围是一种很好的技术,因此不会意外地重复使用它。如果由于某种原因,在调用delete之后指针变量长时间存在(即没有超出范围),那么将它设置为NULL是有用的,这样就不会意外地重复使用它。

  

我应该使用malloc()和free()吗?我是否应该对指向我仍然想要存在的事物的指针进行NULL操作?

否和否 注意:与Java不同,C ++不会跟踪指向对象的指针数量 如果你有多个指针指向一个对象,你需要使用智能指针(你应该使用智能指针)。

  

第二个问题是,当我查看我的任务管理器时,为什么我的进程永远不会“丢弃”内存?它曾经永远不会停止获取,然后我开始正确删除所有内容。或者我想。

应用程序永远不会释放回操作系统(在大多数操作系统的正常情况下) 所以内存永远不会消失(直到应用程序退出) 在内部,内存管理跟踪所有释放,以便可以重用内存。 但如果它用完了,它会向操作系统询问更多,因此在任务管理器中,内存分配将会增加(这不会返回给操作系统)。

  

不会free()或delete使内存使用率下降吗?

没有

  

我应该通过链接列表来实现malloc'ing和释放内存的哪些做法?

您应该使用智能指针,这样您无需担心何时删除对象。
它们还使您的代码异常安全。

但是如果你使用指针。调用delete删除一个元素然后将value设置为NULL(在调用delete之后指针范围仍处于活动状态)。

注意:boost:shared_pointer与Java指针非常相似。它跟踪指针的数量,并在销毁对象的最后一个引用时删除对象。你不需要做任何删除(就像Java一样),你真正需要做的就是调用new(就像Java一样)。