【问题标题】:Regrow memory allocated by operator new()?重新增长运算符 new() 分配的内存?
【发布时间】:2011-01-19 15:38:22
【问题描述】:

以这种方式分配时,是否可以重新增长operator new() 分配的内存:

char* buf = new char[60];

C++ FAQ 表示new 分配的内存无法通过 realloc 调整大小,那么重新增长new 分配的内存的正确方法是什么?

【问题讨论】:

标签: c++


【解决方案1】:

正确的做法是不做。

如果之前的分配不够大,只需分配新内存。

或者使用std::vector,它非常有效地封装了所有这些功能。

【讨论】:

    【解决方案2】:

    正确的方法是使用std::vectorstd::string,具体取决于您对数组的特定用途——让C++ 为您处理分配。

    如果您必须使用new,则必须重新分配和复制内存。这个简单的模板函数向您展示了基础知识:

    template <typename T>
    T *GrowArray(T *oldArray, size_t oldCount, size_t newCount) {
        T *newArray = new T[newCount];
        if (oldArray) {
            std::copy(oldArray, oldArray + std::min(oldCount, newCount), newArray);
            delete[] oldArray;
        }
        return newArray;
    }
    

    请注意,在大多数实现和大多数用例中,这基本上是 realloc() 所做的,减去类型安全。如果这对您来说效率低下,那么realloc() 可能没有做得更好。

    【讨论】:

    • +1 用于正确(一目了然)代码的正确解决方案,但调用此方法 GrowArray 有点误导。调用后原来的指针就不行了。
    • @John - 没有任何适当的文档无法处理。 :)
    • 您对realloc 的评论并不正确。虽然realloc 可能 执行与您发布的函数类似的操作,但它同样可能使用特定于操作系统的知识来“扩展”数组而不复制数组的内容。例如,在某些 Linux 版本上,malloc 返回的内存块前面带有一个程序员无法访问但内部实现可以访问的大小变量。当realloc 被调用时,实现可以检查这个变量,看看是否可以在不复制所有内容的情况下扩展数组。
    • @Charles:我知道——我在简化。对于大小增加少量/不跨越页面边界的调用,是的,操作系统将能够优化而不是重新分配。但是,对于更大的调整大小,我的 cmets 站着。
    • @John:调用成功后原来指向realloc的指针也不好。
    【解决方案3】:

    【讨论】:

      【解决方案4】:

      唯一的办法就是做第二个new,复制内容然后删除旧的内存块:

      char *tmpbuff = new char[70];
      memcpy(tmpbuff, buff, 60 * sizeof(char));
      delete [] buff;
      buff = tmpbuff;
      

      (不...C++不等于STL,所以没有STL的生活是有的:-))

      【讨论】:

        猜你喜欢
        • 2012-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-08-13
        • 1970-01-01
        • 1970-01-01
        • 2011-06-23
        • 1970-01-01
        相关资源
        最近更新 更多