【问题标题】:c++ two dimensional array questionc++二维数组题
【发布时间】:2011-08-15 17:42:55
【问题描述】:

我想创建一个指向二维指针数组的指针(宽度和高度为x)。
这段代码会达到我的预期吗? (创建数组元素,写出一些关于它们的信息,然后释放所有分配的内存。)

int main(int argc, char** argv) {
    int x = 3;
    Node ***array = new Node**[x];
    for (int i = 0; i < 3; i++) {
        array[i] = new Node*[x];
        for (int j = 0; j < x; j++) {
            array[i][j] = new Node(i, j); /* Node::Node(int row, int col) */
        }
    }
    /* ....... */
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < x; j++) {
            cout << array[i][j]->row << ", " << array[i][j]->col << endl;
        }
    }
    /* ....... */
    for (int i = 0; i < x; i++) {
        for (int j = 0; j < x; j++) {
            delete array[i][j];
            //array[i][j] = NULL;
        }
        delete[] array[i];
        //array[i] = NULL;
    }
    delete[] array;
    //array = NULL;
    return 0;
}

或者我应该创建一个vectorvector 的指向Node 对象的指针吗?
或者我应该在堆栈上分配我的对象吗?

(我使用的是指针,因为在 Java 或 C# 中,创建对象时必须始终使用 new 关键字(但是,我不认为所有对象都在堆内存中),而且我读到堆上有更多可用空间。)

我使用带有new 关键字的指针的另一个原因是,我想创建指向同一个对象的多个指针。 我应该在堆栈上创建一个对象,然后只创建指向该对象的指针吗?

【问题讨论】:

  • 一个节点有多大?你能给我们看一下 Node 的声明吗?
  • 节点对象只是一个例子,它有两个公共int字段。

标签: c++ pointers multidimensional-array


【解决方案1】:

我建议您使用vector&lt; vector&lt;Node&gt; &gt;boost::multi_array,或者您可以汇总您自己的动态二维数组类(这并不难),它是一个平面一维std::vector 的包装器。

上述所有解决方案都将您的 Node 对象存储在堆中,并负责清理内存。

这是一个简单的 Matrix 类的示例,它是 std::vector&lt;T&gt; 的包装器:

#include <iostream>
#include <vector>

template <class T>
class Matrix
{
public:
    Matrix() : width_(0), height_(0), vec_(0) {}

    Matrix(size_t width, size_t height)
        : width_(width), height_(height), vec_(width*height) {}

    size_t size() const {return vec_.size();}

    size_t width() const {return width_;}

    size_t height() const {return height_;}

    // Clears all preexisting data
    void resize(size_t width, size_t height)
        {width_ = 0; height_ = 0; vec_.clear(); vec_.resize(width*height);}

    void clear() {width_ = 0; height_ = 0; vec_.clear();}

    T& operator()(size_t col, size_t row) {return vec_[row*width_ + col];}

    const T& operator()(size_t col, size_t row) const
        {return vec_[row*width_ + col];}

private:
    size_t width_;
    size_t height_;
    std::vector<T> vec_;
};

int main()
{
    Matrix<double> a(3, 4);
    a(1, 2) = 3.1415;
    std::cout << a(1,2) << "\n";
}

它使用operator() 来模仿c 风格多维数组的array[2][4] 语法。您不必担心浅拷贝、释放内存等问题,因为 vector 已经解决了这些问题。

【讨论】:

    【解决方案2】:

    您是否考虑过使用Boost.Multidimensional.Array

    它看起来可以充分解决您要解决的问题。如果您的问题可以接受,您可以将它与 Node* 或实际的 Node 类型一起使用。

    【讨论】:

      【解决方案3】:

      您的代码看起来正确,但我建议您创建一个由 Node 对象组成的向量 vector 类管理自己的内存,因此您永远不必担心忘记 delete 任何内容。

      您甚至不必将其设为Node 指针向量的向量。如果您说my_vector.push_back(my_node),它会将my_node 复制到向量的堆分配内存中。如果您从函数返回向量,则节点会随之而来(它不会在函数末尾丢失,就像堆栈分配的对象一样)。例如:

      // declare a vector of nodes on the stack
      vector<node> nodes;
      
      // declare a Node object on the stack
      Node my_node(/*arguments*/);
      
      // copy my_node (on the stack) into the vector's memory (on the heap)
      nodes.push_back(my_node);
      
      // (return 'nodes' from this function and store it somewhere)
      

      注意nodes 中的节点与my_node 是不同的对象。如果您使用new 创建my_node,push_back() 将复制指针(而不是对象本身),并且向量中的对象将与您使用new 创建的对象相同。如果这样做,您就拥有该对象,并且您必须记住在完成后将其删除。如果您让向量拥有该对象(如我的代码示例中所示),它将为您处理。

      【讨论】:

        猜你喜欢
        • 2018-11-15
        • 2020-01-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-08
        • 2016-05-03
        相关资源
        最近更新 更多