我需要动态分配大小在运行时给出的1-D和2-D数组。
我设法“发现”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));
答案 0 :(得分:50)
如您所发现的那样,在运行时给出维度时,需要动态分配数组。
但是,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));
答案 1 :(得分:9)
您将两个问题混为一谈,即动态分配和可调整大小的容器。你不需要担心动态分配,因为你的容器已经为你做了,所以就这样说:
matrix name(sizeX, std::vector<double>(sizeY));
这会使name
成为具有自动存储持续时间的对象,您可以通过name[i][j]
访问其成员。
答案 2 :(得分:4)
你正在做什么应该基本上工作,然而:
通常,不会动态分配对象
如果你想要一个矢量,请执行以下操作:
std::vector<double> vec(size);
不是这个:
std::vector<double>* vec = new std::vector<double>(size);
后者为您提供了一个必须删除的指针。前者为你提供了一个向量,当它超出范围时,它会自行清理。 (当然,它在内部动态分配对象,但诀窍在于它由类本身处理,您无需在用户代码中担心它。)
答案 3 :(得分:2)
这是正确的,但可以提高效率。
您可以使用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_;
};
答案 4 :(得分:2)
虽然其他答案的要点非常正确(不要通过new动态分配向量,而是让向量进行分配),如果你正在考虑向量和矩阵的术语(例如线性代数),你可能想考虑使用特征矩阵库。
答案 5 :(得分:1)
您不会动态分配容器。如果他们自己不是手动管理的,他们可以自动管理内存。
当您使用push_back
(或insert
)添加新项目时,向量会增长,您可以从一开始就使用构造函数的参数选择其大小,然后您可以使用{{ 1}}方法。
使用构造函数创建带有大小的向量向量,如下所示:
resize
这意味着:std::vector< std::vector<double> > matrix(size, std::vector<double>(sizeY));
size
个实例,每个std::vector<double>
个实例包含sizeY
两倍(初始化为0.0)。
答案 6 :(得分: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;
}
答案 7 :(得分: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;
}
答案 8 :(得分:-1)
如果您不需要在运行时调整数组大小,那么您可以使用标准数组(在运行时分配)!
但是,如果确实需要在运行时调整数组大小,那么可以使用以下(修订版)代码:
#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));
从本质上讲,我所做的就是删除一个括号((
)。