[英]How do you 'realloc' in C++?
How can I realloc
in C++?如何在 C++ 中重新
realloc
? It seems to be missing from the language - there is new
and delete
but not resize
!语言中似乎缺少它 - 有
new
和delete
但没有resize
!
I need it because as my program reads more data, I need to reallocate the buffer to hold it.我需要它,因为当我的程序读取更多数据时,我需要重新分配缓冲区来保存它。 I don't think
delete
ing the old pointer and new
ing a new, bigger one, is the right option.我不认为
delete
ing 旧指针和new
ing 一个新的、更大的指针,是正确的选择。
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 数组。
The right option is probably to use a container that does the work for you, like std::vector
.正确的选择可能是使用为您完成工作的容器,例如
std::vector
。
new
and delete
cannot resize, because they allocate just enough memory to hold an object of the given type. new
和delete
不能调整大小,因为它们只分配足够的内存来容纳给定类型的对象。 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[]
但几乎没有理由使用它们。
What realloc
does in C is likely to be just a malloc
, memcpy
and free
, anyway, although memory managers are allowed to do something clever if there is enough contiguous free memory available.无论如何,
realloc
在 C 中所做的很可能只是malloc
、 memcpy
和free
,尽管如果有足够的连续空闲内存可用,内存管理器可以做一些聪明的事情。
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[]
和delete[]
一起使用的根本原因,它做了类似的事情:
newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;
Obviously oldsize
would be retrieved from a secret location, same is it is in delete[]
, and Type
would come from the type of the operand.显然
oldsize
将从一个秘密位置检索,同样是在delete[]
,并且Type
将来自操作数的类型。 resize[]
would fail where the Type is not copyable - which is correct, since such objects simply cannot be relocated.在类型不可复制的情况下,
resize[]
会失败——这是正确的,因为这些对象根本无法重新定位。 Finally, the above code default-constructs the objects before assigning them, which you would not want as the actual behaviour.最后,上面的代码在分配对象之前默认构造对象,这是您不希望作为实际行为的。
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.有一个可能的优化,其中
newsize <= oldsize
,为新缩小的数组“越过末尾”的对象调用析构函数,并且不执行任何其他操作。 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.该标准必须定义此优化是必需的(如
resize()
向量时)、允许但未指定、允许但依赖于实现还是禁止。
The question you should then ask yourself is, "is it actually useful to provide this, given that vector
also 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++.如果您想以 C 方式进行可调整大小的缓冲区,请使用
malloc / free / realloc
,它们在 C++ 中可用。 If you want to do resizeable buffers the C++ way, use a vector (or deque
, if you don't actually need contiguous storage).如果您想以 C++ 方式进行可调整大小的缓冲区,请使用 vector (或
deque
,如果您实际上不需要连续存储)。 Don't try to mix the two by using new[]
for raw buffers, unless you're implementing a vector-like container.不要尝试通过对原始缓冲区使用
new[]
来混合两者,除非您正在实现类似向量的容器。
Here's a std::move example implementing a simple vector with a realloc (*2 each time we hit the limit).这是一个 std::move 示例,它实现了一个带有 realloc 的简单向量(每次达到限制时*2)。 If there's a way to do better than the copy I have below, pls let me know.
如果有比我下面的副本做得更好的方法,请告诉我。
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);
}
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. Vector会抱怨。 That's why arrays, malloc and new still exists.
这就是数组、malloc 和 new 仍然存在的原因。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.