你如何在 C++ 中“重新分配”?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3482941/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 12:56:18  来源:igfitidea点击:

How do you 'realloc' in C++?

c++new-operatorreallocdelete-operator

提问by bodacydo

How can I reallocin C++? It seems to be missing from the language - there is newand deletebut not resize!

我如何realloc在 C++ 中?这似乎是从语言缺少的-有newdelete,但不resize

I need it because as my program reads more data, I need to reallocate the buffer to hold it. I don't think deleteing the old pointer and newing a new, bigger one, is the right option.

我需要它,因为当我的程序读取更多数据时,我需要重新分配缓冲区来保存它。我不认为delete使用旧指针并new使用新的更大的指针是正确的选择。

采纳答案by f0b0s

Use ::std::vector!

使用 ::std::vector!

Type* t = (Type*)malloc(sizeof(Type)*n) 
memset(t, 0, sizeof(Type)*m)

becomes

变成

::std::vector<Type> t(n, 0);

Then

然后

t = (Type*)realloc(t, sizeof(Type) * n2);

becomes

变成

t.resize(n2);

If you want to pass pointer into function, instead of

如果要将指针传递给函数,而不是

Foo(t)

use

Foo(&t[0])

It is absolutely correct C++ code, because vector is a smart C-array.

它是绝对正确的 C++ 代码,因为 vector 是一个智能 C 数组。

回答by Thomas

The right option is probably to use a container that does the work for you, like std::vector.

正确的选择可能是使用为您完成工作的容器,例如std::vector.

newand deletecannot resize, because they allocate just enough memory to hold an object of the given type. The size of a given type will never change. There are new[]and delete[]but there's hardly ever a reason to use them.

new并且delete不能调整大小,因为它们只分配了足够的内存来容纳给定类型的对象。给定类型的大小永远不会改变。有new[]delete[]但几乎没有理由使用它们。

What reallocdoes in C is likely to be just a malloc, memcpyand free, anyway, although memory managers are allowed to do something clever if there is enough contiguous free memory available.

什么realloc做用C很可能只是一个mallocmemcpy并且free,无论如何,虽然内存管理器被允许这样做的很漂亮,如果有足够的可用连续可用内存。

回答by Steve Jessop

Resizing in C++ is awkward because of the potential need to call constructors and destructors.

在 C++ 中调整大小很尴尬,因为可能需要调用构造函数和析构函数。

I don't think there's a fundamental reason why in C++ you couldn't have a resize[]operator to go with new[]and delete[], that did something similar to this:

我不认为在 C++ 中你不能有一个resize[]运算符来使用new[]and的根本原因delete[],它做了类似这样的事情:

newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;

Obviously oldsizewould be retrieved from a secret location, same is it is in delete[], and Typewould come from the type of the operand. resize[]would fail where the Type is not copyable - which is correct, since such objects simply cannot be relocated. Finally, the above code default-constructs the objects before assigning them, which you would not want as the actual behaviour.

显然oldsize会从一个秘密位置检索,同样是在 中delete[],并且Type来自操作数的类型。resize[]在类型不可复制的情况下会失败 - 这是正确的,因为这些对象根本无法重新定位。最后,上面的代码在分配对象之前默认构造对象,这是您不希望作为实际行为的。

There's a possible optimisation where newsize <= oldsize, to call destructors for the objects "past the end" of the newly-ensmallened array and do nothing else. The standard would have to define whether this optimisation is required (as when you resize()a vector), permitted but unspecified, permitted but implementation-dependent, or forbidden.

有一个可能的优化,其中newsize <= oldsize, 为新缩小的数组的“越过末尾”的对象调用析构函数而不做其他任何事情。该标准必须定义此优化是必需的(如resize()向量时)、允许但未指定、允许但依赖于实现还是禁止。

The question you should then ask yourself is, "is it actually useful to provide this, given that vectoralso does it, and is designed specifically to provide a resize-able container (of contiguous memory--that requirement omitted in C++98 but fixed in C++03) that's a better fit than arrays with the C++ ways of doing things?"

然后你应该问自己的问题是,“提供这个是否真的有用,因为它vector也这样做,并且专门设计用于提供一个可调整大小的容器(连续内存--在 C++98 中省略了该要求,但是在 C++03 中修复)这比使用 C++ 做事方式的数组更合适?”

I think the answer is widely thought to be "no". If you want to do resizeable buffers the C way, use malloc / free / realloc, which are available in C++. If you want to do resizeable buffers the C++ way, use a vector (or deque, if you don't actually need contiguous storage). Don't try to mix the two by using new[]for raw buffers, unless you're implementing a vector-like container.

我认为答案被广泛认为是“不”。如果您想以 C 方式进行可调整大小的缓冲区,请使用malloc / free / reallocC++ 中提供的 。如果您想以 C++ 方式进行可调整大小的缓冲区,请使用向量(或者deque,如果您实际上不需要连续存储)。不要尝试通过new[]用于原始缓冲区来混合两者,除非您正在实现类似向量的容器。

回答by Neil McGill

Here's a std::move example implementing a simple vector with a realloc (*2 each time we hit the limit). If there's a way to do better than the copy I have below, pls let me know.

这是一个 std::move 示例,它实现了一个带有 realloc 的简单向量(每次达到限制时*2)。如果有比我下面的副本做得更好的方法,请告诉我。

Compile as:

编译为:

  g++ -std=c++2a -O2 -Wall -pedantic foo.cpp

Code:

代码:

#include <iostream>
#include <algorithm>

template<class T> class MyVector {
private:
    T *data;
    size_t maxlen;
    size_t currlen;
public:
    MyVector<T> () : data (nullptr), maxlen(0), currlen(0) { }
    MyVector<T> (int maxlen) : data (new T [maxlen]), maxlen(maxlen), currlen(0) { }

    MyVector<T> (const MyVector& o) {
        std::cout << "copy ctor called" << std::endl;
        data = new T [o.maxlen];
        maxlen = o.maxlen;
        currlen = o.currlen;
        std::copy(o.data, o.data + o.maxlen, data);
    }

    MyVector<T> (const MyVector<T>&& o) {
        std::cout << "move ctor called" << std::endl;
        data = o.data;
        maxlen = o.maxlen;
        currlen = o.currlen;
    }

    void push_back (const T& i) {
        if (currlen >= maxlen) {
            maxlen *= 2;
            auto newdata = new T [maxlen];
            std::copy(data, data + currlen, newdata);
            if (data) {
                delete[] data;
            }
            data = newdata;
        }
        data[currlen++] = i;
    }

    friend std::ostream& operator<<(std::ostream &os, const MyVector<T>& o) {
        auto s = o.data;
        auto e = o.data + o.currlen;;
        while (s < e) {
            os << "[" << *s << "]";
            s++;
        }
        return os;
    }
};

int main() {
    auto c = new MyVector<int>(1);
    c->push_back(10);
    c->push_back(11);
}

回答by some guest

try something like that:

尝试这样的事情:

typedef struct Board
{
    string name;
    int size = 0;
};

typedef struct tagRDATA
{
    vector <Board> myBoards(255);

    // Board DataBoard[255];
    int SelectedBoard;

} RUNDATA;

Vector will complain. That's why arrays, malloc and new still exists.

Vector会抱怨。这就是数组、malloc 和 new 仍然存在的原因。