类应该自己管理动态内存吗?



如果一个类需要动态分配内存(例如std::vector),是否可以接受类内部简单地分配和释放内存,使用操作符newmalloc?

答案对我来说并不完全明显。缺乏像垃圾收集语言那样管理内存分配的系统显然是授权的;但另一方面,正是这种缺乏协调导致了记忆的浪费。例如,制作一个"假"分配器,它只是将堆栈内存传递给一个对象,在正常情况下,需要动态内存,但程序员可以断言它永远不会需要超过X个字节,这将是非常微不足道的。

也许你认为这个问题在大地址空间的时代是无关紧要的,但是回到硬件上感觉有点蹩脚,毕竟这是c++。

编辑

我现在意识到我对这个问题是多么的模棱两可……让我再解释一下。

当我说"浪费内存"时,我特别指的是发生在堆碎片中的内存浪费。减少堆碎片是在c++中创建内存管理系统最引人注目的一点,因为(正如许多注释所指出的)析构函数已经处理了资源管理方面的事情。当你的分配基本上是随机的(你不知道你的新内存相对于其他分配的内存在哪里),并且每个类都可能分配时,你就会遇到面向数据的设计试图解决的那种问题:糟糕的数据局部性。

所以问题是:有一个类来做内存管理、对象管理、堆压缩,也许还有统计跟踪(为了调试目的),以最有效地利用内存和数据位置,这有意义吗?[在这个视图中,每个动态分配内存的类或函数都必须以某种方式获得该类的引用。]

还是让每个类都可以分配,而不必使其成为该类接口的一部分?

如果一个类需要动态分配内存(例如std::vector),是否可以接受类内部简单地分配和释放内存,使用newmalloc操作符?

通常,我们有两类:

  • 资源管理器(包括动态内存);
  • "业务logic"类。

大多数情况下,我们不应该将资源管理层和域逻辑层混合在一起。

所以,如果你的类是管理器原始资源的,它只分配/释放,初始化/反初始化它的资源,不做任何其他事情。在这种情况下,new是可以的,甚至是必要的(例如,你不能在写自己的动态数组时使用std::vector,否则你根本不需要写它)。看到RAII。

如果你的类包含一些应用逻辑 ,它不允许显式分配动态内存,打开套接字等,但它使用其他raii类。在这个高级层次上,c++为你提供了一些GC语言没有的东西:它让RAII所有者管理文件、套接字等——任何类型的资源,而不仅仅是原始字节的堆内存,所以你不需要手动Java/c#风格的使用资源进行尝试,无论你在哪里创建一个非原始内存管理器对象——编译器会在你有RAII类的时候为你做这些。

最新更新