动态分配向量(或向量的向量)
allocating vectors (or vectors of vectors) dynamically
我需要动态分配一维和二维数组,它们的大小在运行时给定。
我设法"发现"了std::vector
,我认为它符合我的目的,但我想问一下我所写的是否正确和/或可以改进。
这就是我正在做的:
#include <vector>
typedef std::vector< std::vector<double> > matrix;
//... various code and other stuff
std::vector<double> *name = new std::vector<double> (size);
matrix *name2 = new matrix(sizeX, std::vector<double>(sizeY));
正如您所发现的,当您的维度在运行时给定时,需要动态分配数组。
然而,std::vector
已经是这个过程的包装器,所以动态分配向量就像一个双正数。这是多余的。写(c++ 98):
#include <vector>
typedef std::vector< std::vector<double> > matrix;
matrix name(sizeX, std::vector<double>(sizeY));
或(c++ 11及更新版本):
#include <vector>
using matrix = std::vector<std::vector<double>>;
matrix name(sizeX, std::vector<double>(sizeY));
您正在合并两个问题,动态分配和可调整大小的容器。您不需要担心动态分配,因为您的容器已经为您做了,所以只需这样说:
matrix name(sizeX, std::vector<double>(sizeY));
这将使name
成为一个具有自动存储持续时间的对象,并且您可以通过name[i][j]
访问它的成员。
你所做的应该基本有效,然而:
通常,不动态分配对象
如果你想要一个向量,这样做:
std::vector<double> vec(size);
不是这样的:
std::vector<double>* vec = new std::vector<double>(size);
给你一个指针,你必须删除它。前者给你一个向量,当它超出作用域时,它会自我清理。(当然,在内部,它动态地分配对象,但诀窍是这是由类本身处理的,您不需要在用户代码中担心它)。
这是正确的,但可以提高效率。
你可以使用boost多维数组:http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/user.html
或者,您可以为它实现自己的类并自己处理索引。也许是这样的(没有经过很好的测试):
#include <vector>
#include <cassert>
template <typename T, typename A = std::allocator<T> >
class Array2d
{
public:
typedef Array2d<T> self;
typedef std::vector<T, A> Storage;
typedef typename Storage::iterator iterator;
typedef typename Storage::const_iterator const_iterator;
Array2d() : major_(0), minor_(0) {}
Array2d(size_t major, size_t minor)
: major_(major)
, minor_(minor)
, storage_(major * minor)
{}
template <typename U>
Array2d(size_t major, size_t minor, U const& init)
: major_(major)
, minor_(minor)
, storage_(major * minor, u)
{
}
iterator begin() { return storage_.begin(); }
const_iterator begin() const { return storage_.begin(); }
iterator end() { return storage_.end(); }
const_iterator end() const { return storage_.end(); }
iterator begin(size_t major) {
assert(major < major_);
return storage_.begin() + (major * minor_);
}
const_iterator begin(size_t major) const {
assert(major < major_);
return storage_.begin() + (major * minor_);
}
iterator end(size_t major) {
assert(major < major_);
return storage_.begin() + ((major + 1) * minor_);
}
const_iterator end(size_t major) const {
assert(major < major_);
return storage_.begin() + ((major + 1) * minor_);
}
void clear() {
storage_.clear();
major_ = 0;
minor_ = 0;
}
void clearResize(size_t major, size_t minor)
{
clear();
storage_.resize(major * minor);
major_ = major;
minor_ = minor;
}
void resize(size_t major, size_t minor)
{
if ((major != major_) && (minor != minor_))
{
Array2d tmp(major, minor);
swap(tmp);
// Get minimum minor axis
size_t const dist = (tmp.minor_ < minor_) ? tmp.minor_ : minor_;
size_t m = 0;
// copy values across
for (; (m < tmp.major_) && (m < major_); ++m) {
std::copy(tmp.begin(m), tmp.begin(m) + dist, begin(m));
}
}
}
void swap(self& other)
{
storage_.swap(other.storage_);
std::swap(major_, other.major_);
std::swap(minor_, other.minor_);
}
size_t minor() const {
return minor_;
}
size_t major() const {
return major_;
}
T* buffer() { return &storage_[0]; }
T const* buffer() const { return &storage_[0]; }
bool empty() const {
return storage_.empty();
}
template <typename ArrRef, typename Ref>
class MajorProxy
{
ArrRef arr_;
size_t major_;
public:
MajorProxy(ArrRef arr, size_t major)
: arr_(arr)
, major_(major)
{}
Ref operator[](size_t index) const {
assert(index < arr_.minor());
return *(arr_.buffer() + (index + (major_ * arr_.minor())));
}
};
MajorProxy<self&, T&>
operator[](size_t major) {
return MajorProxy<self&, T&>(*this, major);
}
MajorProxy<self const&, T const&>
operator[](size_t major) const {
return MajorProxy<self&, T&>(*this, major);
}
private:
size_t major_;
size_t minor_;
Storage storage_;
};
虽然其他答案的要点非常正确(不要通过new动态分配向量,而是让向量进行分配),但如果您正在考虑向量和矩阵(例如线性代数),您可能要考虑使用Eigen矩阵库。
不能动态分配容器。如果它们本身不是手动管理的,它们可以自动为您管理内存。
当您使用push_back
(或insert
)添加新项时,vector会增长,您可以从构造函数的参数开始选择它的大小,然后可以使用resize
方法调整它的大小。
用构造函数创建一个具有大小的vector的vector:
std::vector< std::vector<double> > matrix(size, std::vector<double>(sizeY));
这意味着:std::vector<double>
的size
个实例,每个实例包含sizeY
双精度(初始化为0.0)。
有时您不想填充堆栈,并且您的内存需求很大。因此,您可能希望使用vector>动态创建,特别是在创建给定行和col值的表时。
这是我在c++ 11中的看法
int main() {
int row, col;
std::cin >> row >> col;
auto *arr = new std::vector<std::vector<int>*>(row);
for (int i=0; i<row; i++) {
auto *x = new std::vector<int>(col, 5);
(*arr)[i] = x;
}
for (int i=0; i<row; i++) {
for(int j=0; j<col; j++) {
std::cout << arr->at(i)->at(j) << " ";
}
std::cout << std::endl;
}
return 0;
}
#include < iostream >
#include < vector >
using namespace std;
int main(){
vector<int>*v = new vector<int>(); // for 1d vector just copy paste it
v->push_back(5);
v->push_back(10);
v->push_back(20);
v->push_back(25);
for(int i=0;i<v->size();i++){
cout<<v->at(i)<<" ";
}
cout<<endl;
delete v;
system("pause");
return 0;
}
如果您不需要在运行时调整数组大小,那么您可以使用标准数组(在运行时分配)!
但是,如果你确实需要在运行时调整数组的大小,那么你可以使用以下(修改过的)代码:
#include <vector>
typedef std::vector< std::vector<double> > matrix;
//... various code and other stuff
std::vector<double> *name = new std::vector<double> (size);
matrix *name2 = new matrix(sizeX, std::vector<double>(sizeY));
实际上,我所做的只是删除了一个括号((
)。
- C++ 将抽象类型的动态分配对象传递给函数并存储在向量中
- 动态分配特征向量的模因
- 代码超出范围.如何动态分配此向量?
- 在读取大型 txt 文件时动态分配结构内的向量
- 通过引用和动态分配传递向量
- 是否可以动态分配向量?
- 附加到具有非动态分配堆栈的向量
- 使用嵌套向量动态分配方阵
- 如何释放动态分配的向量
- 如何在C++中使用"new"动态分配向量数组?
- 如何创建指向动态分配对象的指针向量
- 你能动态分配一个向量吗?
- 在C++中动态分配向量的安全方法是什么
- 动态分配随机特征向量Xd
- 另一个向量与动态分配的数组
- 对象的 C++ 向量,包含动态分配的内存 - "擦除"不起作用
- 将动态分配的变量移动到向量中
- 具有动态分配成员的结构体的向量
- 动态分配带有向量的结构
- 为什么valgrind显示泄漏,即使包含动态分配对象的向量被释放