【问题标题】:Creating objects in C++ not using "new"不使用“new”在 C++ 中创建对象
【发布时间】:2011-04-13 11:51:11
【问题描述】:

我想做一个程序,让我们说代表一个矩阵 现在矩阵将由一个向量表示,向量中的每个对象都将 表示一个单元格示例:向量 现在在构造矩阵时,构造函数接收要插入矩阵的单元列表。 编译时列表大小未知

我有兴趣在不使用堆内存的情况下创建这个矩阵。换句话说,不使用“new”或“delete”这个词创建对象 如果我不知道要在向量中插入多少对象,有什么办法吗?

【问题讨论】:

  • 为什么你反对在堆上分配这个对象?这就是堆的用途(嗯,至少是主要的事情之一)。
  • 为什么你认为避免堆是个好主意?如果矩阵非常大且非稀疏,因此无法放入堆栈怎么办?
  • 除非您有非常具体的理由避免使用new,否则这听起来很糟糕。
  • @kevin:那么,您是否尝试使用std::vector?那会更有意义。
  • std::vector 可能实际上并没有避免任何堆使用,但至少您不需要自己管理它。

标签: c++ object new-operator delete-operator


【解决方案1】:

有一种特殊的方法可以使用 new 在堆栈中分配内存,或者使用所谓的 placement new 运算符作为静态存储。使用这个版本的 new,你保留了一块内存,并且你明确地告诉 new 你想在哪里存储一个特定的变量。它的工作原理如下:

   #include <new>
   int main()
   {
      char buffer[500];  // chunk of memory
      int p*;
      p = new (buffer) int[10];
   }

请注意,您需要包含 new 标头才能使用这个特殊的 new 运算符。在这种情况下,当您使用自动存储时,内存将在离开声明它的块(主块)时被释放。

参考资料:C++ Primer plus。第 9 章。第 420 页

【讨论】:

  • buffer 不能保证与int 适当对齐。
  • 感谢您的提示。在书中看到这个例子感觉很奇怪:)
  • 但这使用了“新”这个词。 OP 不想要“新”或“删除”。暂时不投反对票!
  • 我认为他的意思是他不想使用堆,因此不想使用标准的动态内存分配器 new 和 deallocator delete。使用placement new,您不必分配动态内存,也不需要使用delete 来释放内存。
【解决方案2】:

如果不使用汇编指令直接(因此依赖于平台)操作程序/函数的堆栈框架,则没有标准的方法可以做到这一点 - 我非常反对。是什么阻止您使用堆?

【讨论】:

    【解决方案3】:

    使用alloca获取指针,然后使用就地new操作符:

    void *p = alloca(sizeof(Class));
    new (p) Whatever(arguments);
    

    不过,在使用之前阅读alloca 手册页! 要非常小心。正如 Jim Brissom 所说,alloca 不可移植。

    您不需要delete。函数返回时会释放内存

    【讨论】:

    • 把这样的资源管理包起来。手动进行内存管理 == 不好。
    • 抛开可移植性问题不谈,alloca 返回的指针是否保证与Whatever 正确对齐?
    • 函数返回时不会调用类析构函数。如果该类有任何指针,您可能会造成内存泄漏。
    【解决方案4】:

    有一种方法,它非常有限且非常非正统。您需要创建一个静态大小的 unsigned char 数组,它构成一个内存池。对象列表的大小将受到限制。您需要为该类重载 new 运算符(和 delete 运算符)以专门针对此类内存池。

    也就是说,确实没有充分的理由走这条路。

    【讨论】:

    • IIRC,您所描述的新放置在 Windows 打印机 DDK 中很常见。
    • 事实上,如果有必要的话,我认为这是将对象放到堆中无法分页的位置的正确方法。
    【解决方案5】:

    好吧,如果你不想在堆上使用内存,你还想从哪里获取它?

    a) 取决于系统 - 您可以要求操作系统为您分配一些内存。但这是不好的风格(取决于系统),并且将使用相同的 RAM ......只是以不同的方式分配。例如,Windows 32 中的 ::GlobalAlloc 或 ::LocalAlloc 如果您真的有兴趣这样做,就会这样做。

    b) 内存映射文件——如果你问这可能会很有趣,因为你认为你没有足够的可用 RAM 并且访问时间不是问题。

    c) 求助于诸如 malloc/free 之类的 C 函数并强制转换指针...从堆中获取内存,只是避免使用“new”和“delete”关键字。

    但是,如果没有信息为什么您想避免新建/删除,很难说出什么“好”的解决方案。 您需要动态内存分配,这两个工具就是这样做的。

    您能否解释/改写您的问题,以便获得更准确的答案?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多