动态分配内存

时间:2019-04-14 22:59:21

标签: c++

我一般不熟悉C ++和编程,所以如果这是一个琐碎的问题,我深表歉意。我正在尝试初始化2个大小为[600] [600]的数组并键入str,但是我的程序不断崩溃。我认为这是因为这两个数组超出了堆栈的内存限制。另外,N由用户指定,因此我不确定我是否可以在此处使用new,因为它不是常量表达式。

我的代码:

#include<iostream>

using namespace std;

struct str {
int x;
int y;
int z;
};
int main(){
cin>>N;
str  Array1[N][N]; //N can be up to 200
str  Array2[N][N];
};

我如何在堆中初始化它们?我知道,对于一维数组,我可以使用向量,但是我不知道这是否可以以某种方式应用于二维数组。

3 个答案:

答案 0 :(得分:2)

二维数组在C ++中的工作方式

一维数组易于实现和取消引用。假设数组名称为arr,则只需进行一次取消引用即可访问元素。

具有2个或更多维的数组(无论是动态数组还是基于堆栈的数组)都需要更多步骤来创建和访问。为了在矩阵和矩阵之间进行类比,如果arr是2D数组,并且您想访问特定元素,例如arr[row][col],则此步骤实际上有2个取消引用。第一个arr[row]使您可以访问row元素的第col行。第二个也是最后一个arr[row][col]可以达到您所需的确切元素。

因为arr[row][col]要求2个解引用才能获得访问权限,所以arr不再是指针,而是指向指针的指针。关于上述内容,第一个取消引用为您提供了指向特定行(一维数组)的指针,而第二个取消引用为您提供了实际元素。

因此,动态2D数组要求您有一个指向指针的指针。

要分配运行时给定大小的动态2D数组

首先,您需要创建一个指向所选择数据类型的指针的指针数组。由于您的帐户是string,因此,一种解决方法是:

std::cin >> N;
std::string **matrix = new string*[N];

您已经分配了一个行指针数组。最后一步是遍历所有元素并自己分配列:

for (int index = 0; index < N; ++index) {
    matrix[index] = new string[N];
}

现在,您可以像使用普通2D网格一样取消引用它:

// assuming you have stored data in the grid
for (int row = 0; row < N; ++row) {
    for (int col = 0; col < N; ++col) {
        std::cout << matrix[row][col] << std::endl;
    }
}

需要注意的一件事:动态数组比常规的基于堆栈的对应数组在计算上更昂贵。如果可能,请改用STL容器,例如std::vector

编辑:要释放矩阵,请“向后”:

// free all the columns
for (int col = 0; col < N; ++col) {
    delete [] matrix[col];
}

// free the list of rows
delete [] matrix;

答案 1 :(得分:0)

通常,您可以使用“ new”运算符来初始化堆中的内存。 希望这可以帮助您:

// Example program
#include <iostream>

struct str {
int x;
int y;
int z;
};

int main()
{
  int N;
  std::cin>>N;
  str  **Array1 = new str*[N]; //N can be up to 200
  for (int i = 0; i < N; ++i) {
    Array1[i] = new str[N];
  }
  // set value
  for (int row = 0; row < N; ++row) {
    for (int col = 0; col < N; ++col) {
        Array1[row][col].x=10;
        Array1[row][col].y=10;
        Array1[row][col].z=10;
    }
  }
  // get value
  for (int row = 0; row < N; ++row) {
    for (int col = 0; col < N; ++col) {
        std::cout << Array1[row][col].x << std::endl;
        std::cout << Array1[row][col].y << std::endl;
        std::cout << Array1[row][col].z << std::endl;
    }
  }
}

答案 2 :(得分:0)

当要使用new运算符在C ++中分配2D数组时,必须声明(*pointer-to-array)[N],然后使用new type [N][N];分配

例如,您可以按以下方式声明和分配Array1

#define N 200

struct str {
    int x, y, z;
};

int main (void) {

    str (*Array1)[N] = new str[N][N];  /* allocate */

    /* use Array1 as 2D array */

    delete [] Array1;                  /* free memory */
}

但是,理想情况下,您希望让C ++容器库类型vector处理您的内存管理。例如,您可以:

#include<vector>
..
std::vector <std::vector <str>> Array1;

然后填充Array1,为std::vector<str> tmp;的每一行(一维数组)填充临时str,然后Array1.push_back(tmp);添加填充的tmp向量到您的Array1。您的访问仍然可以是2D索引(例如Array1[a][b].x, Array1[a][b].y, ...,但是您可以从容器提供的自动内存管理中受益。与您自己处理内存相比,它更健壮,更不易出错。