alocação de vetores (ou vetores de vetores) dinamicamente

Eu preciso alocar dinamicamente matrizes 1-D e 2-D cujos tamanhos são fornecidos em tempo de execução.

Consegui “descobrir” std::vector e acho que se encheckbox em meus propósitos, mas gostaria de perguntar se o que escrevi está correto e / ou pode ser melhorado.

Isso é o que estou fazendo:

 #include  typedef std::vector< std::vector > matrix; //... various code and other stuff std::vector *name = new std::vector (size); matrix *name2 = new matrix(sizeX, std::vector(sizeY)); 

A alocação dinâmica de matrizes é necessária quando suas dimensões são dadas em tempo de execução, como você descobriu.

No entanto, std::vector já é um wrapper em torno desse processo, portanto, alocar dinamicamente vetores é como um duplo positivo. É redundante.

Apenas escreva:

 #include  typedef std::vector< std::vector > matrix; matrix name(sizeX, std::vector(sizeY)); 

Você está confundindo dois problemas, alocação dinâmica e contêineres redimensionáveis. Você não precisa se preocupar com a alocação dinâmica, já que o seu contêiner faz isso por você, então apenas diga assim:

 matrix name(sizeX, std::vector(sizeY)); 

Isto tornará o name um object com duração de armazenamento automático, e você poderá acessar seus membros através do name[i][j] .

O que você está fazendo basicamente deve funcionar, no entanto :

Em geral, não aloque dinamicamente objects

Se você quiser um vetor, faça o seguinte:

 std::vector vec(size); 

isso não:

 std::vector* vec = new std::vector(size); 

O último lhe dá um ponteiro, que você deve excluir. O primeiro lhe dá um vetor que, quando sai do escopo, limpa depois de si mesmo. (Internamente, é claro, ele aloca dinamicamente objects, mas o truque é que isso é tratado pela própria class, e você não precisa se preocupar com isso no seu código de usuário).

Está correto, mas poderia ser mais eficiente.

Você poderia usar os arrays multidimensionais de boost: http://www.boost.org/doc/libs/1_47_0/libs/multi_array/doc/user.html

Ou você pode implementar sua própria class para isso e lidar com a indexação por conta própria. Talvez algo assim (que não é bem testado):

 #include  #include  template  > class Array2d { public: typedef Array2d self; typedef std::vector 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  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  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 operator[](size_t major) { return MajorProxy(*this, major); } MajorProxy operator[](size_t major) const { return MajorProxy(*this, major); } private: size_t major_; size_t minor_; Storage storage_; }; 

Enquanto os pontos que as outras respostas deram eram muito corretos (não aloque dinamicamente o vetor via novo, mas deixe o vetor fazer a alocação), se você está pensando termos de vetores e matrizes (por exemplo, álgebra linear), você pode querer considere usar a biblioteca de matrizes Eigen.

Você não aloca contêineres dinamicamente. Eles podem gerenciar automaticamente a memory para você, se eles próprios não forem gerenciados manualmente.

Um vetor cresce quando você adiciona novos itens com push_back (ou insert ), você pode escolher seu tamanho desde o início com argumentos para o construtor, e você pode redimensioná-lo mais tarde com o método de resize .

Criar um vetor de vetores com seus tamanhos com o construtor se parece com isto:

 std::vector< std::vector > matrix(size, std::vector(sizeY)); 

Isso significa: instâncias de size de um std::vector , cada um contendo sizeY (inicializado em 0.0).

Se você não precisar resize os tamanhos das matrizes em tempo de execução, poderá usar apenas matrizes padrão (alocadas em tempo de execução)!

No entanto, se você precisar resize matrizes em tempo de execução, poderá usar o seguinte código (revisado):

 #include  typedef std::vector< std::vector > matrix; //... various code and other stuff std::vector *name = new std::vector (size); matrix *name2 = new matrix(sizeX, std::vector(sizeY)); 

Em essência, tudo que fiz foi remover um único colchete ( ( ).