【问题标题】:memory allocation in C++C++中的内存分配
【发布时间】:2010-11-07 16:34:53
【问题描述】:

是否可以使用“new”运算符分配任意内存块? 在 C 语言中,我可以像“void * p = malloc(7);”那样做- 如果内存对齐设置为 1 个字节,这将分配 7 个字节。如何在 C++ 中用 new 操作符做同样的事情?

【问题讨论】:

    标签: c++ memory new-operator


    【解决方案1】:

    在 C++ 中可以使用operator new 分配任意内存块;不是用于构造对象的new 运算符。

    void* pBlock = ::operator new(7);
    

    这些块随后可以通过operator delete 释放。

    ::operator delete(pBlock);
    

    请注意,operator new 将为任何类型的对象分配适当对齐的内存,因此实​​现可能不会完全分配 7 个字节,但malloc (通常)也是如此。 malloc 的 C 客户端通常也需要对齐内存。

    【讨论】:

    • +1 提到那里 一种无需 malloc 和免费的方法 :)
    • 另外,请注意 operator new 通常只是将责任转嫁给 malloc() (在我知道的每个实现中)。正如多米尼克所说,还不如只使用malloc。
    • 非常感谢。这是一个答案(“::operator new”)。我花了很多时间试图弄清楚为什么“:: new(x);”不工作:)
    【解决方案2】:

    其他人已经按照书面形式回答了这个问题,但我建议坚持使用 malloc/free 进行此类分配。

    new 和 delete 用于分配对象。它们分配所需的内存并调用构造函数/析构函数。如果你知道你只需要一个任意的内存块,那么使用 malloc 和 free 是完全合理的。

    【讨论】:

    • 但是如果您正在编写 C++ 代码,我认为使用 new/delete 会更好,因为您将使用它来分配对象。拥有两种类型的内存分配函数会增加更多的混乱。
    • -1。 new/delete 是语言结构,无论您分配/解除分配什么,都会引入类型安全。 malloc/free 是为向后兼容而保留的工件。
    • @RA,如果需要一个任意的通用字节块,那么相信它们是专门的 char 或 unsigned char 或其他任何东西都没有好处—— void* 更诚实和明确。 +1 为 malloc!
    • OP 明确声明他们希望返回一个 void 指针。因此,使用 new/delete 将在他们可能不需要的地方引入类型。如果用例实际上是一个类型数组,那么绝对切换到 new[]。如果他们只是管理一块内存,就没有理由引入类型。
    • +1 从这里。是的,new/delete 添加类型安全,但如果他不想分配任何特定类型,而只是一个空白内存缓冲区,那么 malloc/free 正是这样做的。
    【解决方案3】:

    您不能使用 C++ 的运算符 new 分配 void 指针:您必须分配显式类型,例如 charuint8_t

    char *p = new char[7];
    uint8_t *q = new uint8_t[7];
    ...
    delete [] p;
    delete [] q;
    

    【讨论】:

      【解决方案4】:

      是的,你可以。
      但取决于你在做什么,可能会有更好的技术。

      您能否更新问题并告诉我们您要达到的目标。有了更多的上下文,可以提供更好的解决方案。

      一个例子:
      如果您正在动态分配缓冲区以从套接字读取(因为在编译时不知道大小)。另一种方法是使用向量并动态调整其大小。然后,您可以通过获取第一个元素的地址来获取指向缓​​冲区内部的指针。

      【讨论】:

        【解决方案5】:

        我个人会使用std::vector<char>。您不仅可以获得任意字节块 (guaranteed to be contiguous),还可以将它们放入 RAII 包装器中。当然,没有必要使用std::vector 的任何方法(可能除了resize()),但没有任何惩罚:

        std::vector<char> buffer(7);
        void* p = &buffer[0];
        

        您可以使用std::string,但std::string 暗示“此对象包含在打印时有意义的字符”,而std::vector&lt;char&gt; 暗示“此对象包含任意字节组。”

        【讨论】:

          【解决方案6】:

          我想你可能正在寻找Placement New

          【讨论】:

          • 我只想补充一点,如果您要使用诸如 Placement New 之类的技术,您必须小心。仅在真正需要时才使用它!
          • placement new 与分配内存有何关系?
          • @Miky D:我同意,这就是为什么链接页面上的“危险”一词全部大写。 :-)
          • 也许我误解了这个问题,但我相信它问的是相反的问题。也就是说,不是如何在已经分配的内存空间中创建/初始化对象,而是如何在不执行构造函数调用的情况下分配内存。
          【解决方案7】:

          新字符[7];

          传统上,char 是一个字节,但您可能会发现一些库将类型定义为 BYTE 类型。

          【讨论】:

          • 没关系; char 是实现可以处理的最小类型。如果一个 char 是 16 位,那么一个字节类型不能少于 16 位。请记住 sizeof(char) == 1。始终。
          • @David Thornley: sizeof(char) 不是必须的 1,否则各种编组库会很烦。
          • @florin: sizeof(char) == 1 根据标准。参见 ISO/IEC 14882:2003 的第 5.3.3 节。 “sizeof(char)、sizeof(signed char) 和 sizeof(unsigned char) 为 1;sizeof 应用于任何其他基本类型 (3.9.1) 的结果是实现定义的。”
          • 嗯,是的,sizeof(char) == 1。至少根据 ISO C++ 标准 (open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2914.pdf) 的第 5.3.3 节,但我们不要无聊,我喜欢这个回应更多问题:parashift.com/c++-faq-lite/intrinsic-types.html#faq-26.1
          • @Andreas:这不是我刚才说的吗?
          【解决方案8】:

          您可以使用char* pBuffer = new char[7];,并且由于 sizeof(char) 是 1 字节,您可以将其用作字节缓冲区。另外,释放内存时记得使用delete[](带[])。

          【讨论】:

            猜你喜欢
            • 2014-10-25
            • 2010-12-11
            • 2022-01-21
            • 2010-10-16
            • 1970-01-01
            • 2010-12-21
            • 1970-01-01
            相关资源
            最近更新 更多