指针指针动态二维数组

use*_*041 26 c++ arrays pointers memory-management dynamic-arrays

这个网站上的第一个计时器,所以这里..

我是C++的新手,我目前正在阅读"DS Malik的数据结构使用C++第二版"一书.

在书中,Malik提供了两种创建动态二维数组的方法.在第一种方法中,将变量声明为指针数组,其中每个指针都是整数类型.恩.

int *board[4];
Run Code Online (Sandbox Code Playgroud)

..然后使用for循环创建'列',同时使用指针数组作为'行'.

第二种方法,您使用指针指针.

int **board;
board = new int* [10]; 
Run Code Online (Sandbox Code Playgroud)

等等

我的问题是:哪种方法更好?**方法对我来说更容易可视化,但第一种方法可以大致相同的方式使用.两种方式都可用于制作动态二维数组.

编辑:上面的帖子不够清楚.这是我尝试过的一些代码:

int row, col;

cout << "Enter row size:";
cin >> row;
cout << "\ncol:";
cin >> col;

int *p_board[row];
for (int i=0; i < row; i++)
    p_board[i] = new int[col];

for (int i=0; i < row; i++)
{
    for (int j=0; j < col; j++)
    {
        p_board[i][j] = j;
        cout << p_board[i][j] << " ";
    }
    cout << endl;
}
cout << endl << endl;

int **p_p_board;
p_p_board = new int* [row];
for (int i=0; i < row; i++)
    p_p_board[i] = new int[col];

for (int i=0; i < row; i++)
{
    for (int j=0; j < col; j++)
    {
        p_p_board[i][j] = j;
        cout << p_p_board[i][j] << " ";
    }
    cout << endl;
}
Run Code Online (Sandbox Code Playgroud)

Ale*_*aev 49

第一种方法不能用于创建动态 2D数组,因为通过执行以下操作:

int *board[4];
Run Code Online (Sandbox Code Playgroud)

你基本上int 在堆栈上分配了一个包含4个指针的数组.因此,如果现在使用动态数组填充这4个指针中的每一个:

for (int i = 0; i < 4; ++i) {
  board[i] = new int[10];
}
Run Code Online (Sandbox Code Playgroud)

你最终得到的是具有静态行数(在这种情况下为4)和动态列数(在这种情况下为10)的2D数组.因此它不是完全动态的,因为当您在堆栈上分配数组时,您应该指定一个常量大小,即在编译时已知.动态数组称为动态因为它的大小是没有必要在被称为编译时,而是可以通过在一些变量来确定运行时间.

当你这样做时:

int *board[4];
Run Code Online (Sandbox Code Playgroud)

要么:

const int x = 4; // <--- `const` qualifier is absolutely needed in this case!
int *board[x];
Run Code Online (Sandbox Code Playgroud)

你提供一个在编译时已知的常量(在这种情况下是4或x),这样编译器现在可以为你的数组预先分配这个内存,当你的程序被加载到内存中时,它已经有了这个数量的内存用于board数组,这就是为什么它被称为静态,即因为大小是硬编码的,并且不能动态地改变(在运行时).

另一方面,当你这样做时:

int **board;
board = new int*[10];
Run Code Online (Sandbox Code Playgroud)

要么:

int x = 10; // <--- Notice that it does not have to be `const` anymore!
int **board;
board = new int*[x];
Run Code Online (Sandbox Code Playgroud)

编译器不知道需要多少内存board数组,因此它不预先分配任何内容.但是,当您启动程序,数组的大小将受到的值决定x变量(在运行时)和相应的空间board阵列将在所谓的分配 -在您的计算机上运行的内存区域,所有程序都事先分配未知(在编译时)为个人使用量的内存.

因此,要真正创建动态2D阵列,您必须使用第二种方法:

int **board;
board = new int*[10]; // dynamic array (size 10) of pointers to int

for (int i = 0; i < 10; ++i) {
  board[i] = new int[10];
  // each i-th pointer is now pointing to dynamic array (size 10) of actual int values
}
Run Code Online (Sandbox Code Playgroud)

我们刚刚创建了一个10×10维的方形2D数组.要遍历它并使用实际值填充它,例如1,我们可以使用嵌套循环:

for (int i = 0; i < 10; ++i) {   // for each row
  for (int j = 0; j < 10; ++j) { // for each column
    board[i][j] = 1;
  }
}
Run Code Online (Sandbox Code Playgroud)


Jos*_*eld 9

您为第二种方法描述的内容仅为您提供一维数组:

int *board = new int[10];
Run Code Online (Sandbox Code Playgroud)

这只是分配一个包含10个元素的数组.也许你的意思是这样的:

int **board = new int*[4];
for (int i = 0; i < 4; i++) {
  board[i] = new int[10];
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,我们分配4 int*秒,然后使每个指向动态分配的10 int秒数组.

所以现在我们将其与之进行比较int* board[4];.主要区别在于,当您使用这样的数组时,必须在编译时知道"行"的数量.那是因为数组必须具有编译时固定大小.如果您想要返回此int*s 数组,也可能会出现问题,因为数组将在其范围的末尾被销毁.

行和列都是动态分配的方法需要更复杂的措施来避免内存泄漏.你必须像这样释放内存:

for (int i = 0; i < 4; i++) {
  delete[] board[i];
}
delete[] board;
Run Code Online (Sandbox Code Playgroud)

我必须建议使用标准容器.您可能希望使用std::array<int, std::array<int, 10> 4>std::vector<std::vector<int>>初始化为适当大小的a 或者.