如何realloc使用C ++?这似乎是从语言缺少的-有new和delete,但不resize!
我需要它,因为随着程序读取更多数据,我需要重新分配缓冲区以保存它。我认为delete选择旧指针而new不是新的更大指针是正确的选择。
如何realloc使用C ++?这似乎是从语言缺少的-有new和delete,但不resize!
我需要它,因为随着程序读取更多数据,我需要重新分配缓冲区以保存它。我认为delete选择旧指针而new不是新的更大指针是正确的选择。
Answers:
使用:: std :: vector!
Type* t = (Type*)malloc(sizeof(Type)*n)
memset(t, 0, sizeof(Type)*m)
变成
::std::vector<Type> t(n, 0);
然后
t = (Type*)realloc(t, sizeof(Type) * n2);
变成
t.resize(n2);
如果要将指针传递给函数,而不是
Foo(t)
使用
Foo(&t[0])
这是绝对正确的C ++代码,因为向量是一个智能C数组。
Type* t = static_cast<Type*>(malloc(n * sizeof *t));
t.data()而不是&t[0]
正确的选择可能是使用一个为您完成工作的容器,例如std::vector。
new并且delete无法调整大小,因为它们仅分配足够的内存来容纳给定类型的对象。给定类型的大小永远不会改变。有new[],delete[]但几乎没有理由使用它们。
什么realloc做用C很可能只是一个malloc,memcpy并且free,无论如何,虽然内存管理器被允许这样做的很漂亮,如果有足够的可用连续可用内存。
std::vector-它会在需要时自动增长,并且如果需要,您可以预分配内存reserve()。
std::string顺便说一句也可以。)
std::string可以做到。顺便说一下,也有可能简化您的数据读取。您如何读取数据?
thevector.resize(previous_size + incoming_size),然后是memcpy(或类似的)&thevector[previous_size]。保证向量的数据“像数组一样”存储。
由于可能需要调用构造函数和析构函数,因此C ++中的大小调整很尴尬。
我认为,在C ++中,您无法resize[]使用new[]and运算符是没有根本原因的delete[],它做了类似的事情:
newbuf = new Type[newsize];
std::copy_n(oldbuf, std::min(oldsize, newsize), newbuf);
delete[] oldbuf;
return newbuf;
显然,oldsize它将从一个秘密位置中检索,这与in中的相同delete[],并且Type将来自操作数的类型。resize[]在类型不可复制的地方将失败-这是正确的,因为此类对象根本无法重定位。最后,上面的代码在分配对象之前默认构造了对象,您不希望它们成为实际的行为。
有一个可能的优化方法,其中newsize <= oldsize可以为新缩小的数组的对象“过去”调用析构函数,而不执行其他任何操作。该标准必须定义此优化是必需的(例如,当您resize()使用矢量时),允许但未指定,允许但与实现有关的或禁止的。
然后,您应该问自己的问题是:“提供此功能实际上是否有用,vector并且确实如此,并且专门设计用于提供可调整大小的容器(具有连续内存-C ++ 98中省略了该要求,但在C ++ 03中已修复)是否比使用C ++做事的方式更适合数组?”
我认为答案被普遍认为是“否”。如果要使用C方式执行可调整大小的缓冲区,请使用malloc / free / reallocC ++中可用的。如果要以C ++方式进行可调整大小的缓冲区,请使用向量(或deque,如果实际上不需要连续存储,则使用)。new[]除非您要实现类似矢量的容器,否则不要尝试通过使用原始缓冲区来混合两者。
这是一个std :: move示例,该示例实现了带realloc的简单向量(每次达到极限时,* 2)。如果有比我下面的副本做得更好的方法,请告诉我。
编译为:
g++ -std=c++2a -O2 -Wall -pedantic foo.cpp
码:
#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);
}