【问题标题】:C++ Class constructor 2d Array memory allocationC++ 类构造函数 2d 数组内存分配
【发布时间】:2015-03-12 02:23:27
【问题描述】:

这学期我参加了大学的编程课,只是出于好奇。我们正在做 C++,我非常喜欢它,但过去两周对我来说相当陡峭,这让我感到困扰:

给我一​​个类接口如下:

class GameOfLife(int rows, int cols);
    public:
        GameOfLife();
        void clear();
        void set(int row, int col, int value);
        void set(int row, int col, const char* values);
        int get(int row, int col);
        void print();
        void advance();
   };

我被要求做的第一件事是实现构造函数,以便它根据参数中传递的行数和列数为板分配内存。我以为我了解构造函数,但是对于这个我很迷茫。 在我在私有部分声明 int rows 和 cols 之后,我想到了一些类似于

GameOfLife::GameOfLife(int x, int y){
    rows = x;
    cols = y;
    board = new int* [rows];

但是我既不知道如何在没有编译器对我大喊大叫的情况下处理板的第二维,也不知道如何测试新内存是否实际分配正确。 有什么帮助吗? :(

提前致谢!

【问题讨论】:

  • class GameOfLife(int rows, int cols);开头是错误的,需要把(int rows, int cols)移到构造函数里面。或者这只是某种伪代码?

标签: c++ class constructor multidimensional-array


【解决方案1】:

除了thumbmunkey的correct answer,注意,仅仅因为外部接口规定了一个二维数组并不意味着内部接口必须匹配。

你可以:

int* board = new int[rows * cols];

然后在哪里而不是 get() 返回:

return board[x][y];

应该是:

return board[x * rows + y];

有时一个数组比两个数组更容易考虑。有时不是。取决于你想怎么做(或者是否规定你必须使用一种方法或另一种方法)。

【讨论】:

  • 出于好奇,int*[] 版本在访问的情况下会不会更快?对于int*,您有:i) 一个加法,ii) 一个乘法,iii) 一个解引用,而对于指针数组int*[],只有:i) 两个解引用。不得不说我没有分析任何东西,而且编译器可能已经很好地优化了代码,所以它可能不会产生明显的差异......
  • @vsoftco 甚至不打算下注:)
  • @vsoftco int[] 方式将分配更少的内存。通过rows * sizeof(int*)字节。
  • 虽然int*[] 更灵活:) 但正如你所说,这真的取决于手头的任务。虽然我可能会尝试分析速度差异(如果有的话)。此外,应该提到的是,每当您使用矩阵的所谓“矢量化”执行操作时,您的方法也非常好,即通过将每一行附加到前一行(或顶部的每一列)将其重塑为矢量前一个,取决于约定)。在这种情况下,您已经有了矢量化形式。示例:A * B 的轨迹将被优化,因此它使用矢量化形式。
【解决方案2】:

你必须为每一行分配列数组:

  for(int i=0; i<rows; i++)
      board[i] = new int [cols];

如果分配失败(例如,当您的内存不足时),您将获得一个exception

【讨论】:

    【解决方案3】:

    你现在用board = new int* [rows];做什么 正在分配一个整数指针数组。您仍然需要为 thumbmunkey 正在使用的实际整数分配内存,

    for(int i=0;i<rows;i++)
      board[i] = new int [cols];
    

    【讨论】:

    • i 是关于行,而不是列:(int i=0;i
    【解决方案4】:

    已经有一个类来动态管理内存,它叫做vector。如果您尝试在代码中使用new,那么您最终不得不重新发明轮子并编写数十行已经存在于vector中的样板代码。

    此外,将板子存储在连续数组中更简单,无需使用一堆单独的内存块来保存板子。

    这是一个例子:

    class GameOfLife
    {
    public:
        GameOfLife(int rows, int cols);
        void clear();
        void set(int row, int col, int value);
        void set(int row, int col, const char* values);
        int get(int row, int col);
        void print();
        void advance();
    private:
        int rows, cols;
        std::vector<int> values;
    };
    

    //在cpp文件中

    GameOfLife::GameOfLife(int rows, int cols)
        : rows(rows), cols(cols), values(rows * cols) {}
    
    void GameOfLife::set(int row, int col, int value)
        { values.at(row * cols + col) = value; }
    
    int GameOfLife::get(int row, int col) 
        { return values.at(row * cols + col); }
    

    【讨论】:

      【解决方案5】:

      要领——构造函数、析构函数、getter:

          class GameOfLife
          {
          public:
              GameOfLife(int _rows, int _cols);
              ~GameOfLife ();
      
              int GetRows () {return rows;}
              int GetCols () {return cols;}
              int **GetBoard () {return board;}
      
          private:
              int rows, cols;
              int **board;
          };
      
          GameOfLife::GameOfLife(int _rows, int _cols)
          {
              rows = _rows;
              cols = _cols;
              board = new int *[rows];
              for (int i = 0; i<rows; i++)
                  board[i] = new int[cols];
          }
      
          GameOfLife::~GameOfLife()
          {
              for (int i = 0; i<rows; i++)
                  delete [] board[i];
              delete [] board;
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-07-29
        • 1970-01-01
        • 2010-09-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-17
        相关资源
        最近更新 更多