需要有关 C++ 中二维数组的动态内存分配的帮助
Posted
技术标签:
【中文标题】需要有关 C++ 中二维数组的动态内存分配的帮助【英文标题】:Need help regarding Dynamic Memory Allocation for two dimensional arrays in C++ 【发布时间】:2013-07-30 09:53:22 【问题描述】:我一直在尝试为二维数组分配动态内存。经过大量搜索后,我发现了一个看起来比其他代码更容易的代码,但我仍然无法理解它的每一个细节。有人可以解释一下以下代码如何动态地为数组分配内存。真的很期待帮助和抱歉,但我是 C++ 新手,想学习它。
void main()
int m,n;
cin>>m;
cin>>n;
//Allocate
int *a = new int[m*n];
//Use a[m][n]
for( int i = 0 ; i < m ; i++)
for ( int j = 0 ; j < n ; j++)
a[i*n + j] = 1;
【问题讨论】:
如果您使用的是 C++,请为数组使用正确的 C++ 类型,例如std::vector
或 std::array
而不是 C 风格的内存分配。
这实际上是一个一维数组,长度为row*columns。这在图像处理中很常见。但是该数组的索引就像它是一个 m * n 数组一样。其中 m 是行数,n 是列数。因此 i * n 将索引放在第 i 行,您还必须 + j
才能获得正确的列。
【参考方案1】:
代码只使用一个内存块来表示所有元素,因此要访问示例( i, j )
,它需要计算索引为i * num_rows + j
(或num_colums,具体取决于您如何看待它)。
但正如评论,不要使用new int....
,使用类似的东西
std::vector< int > a( m * n );
【讨论】:
对于二维数组使用std::vector<std::vector<int> > a(m, std::vector<int>(n));
@Johny 是的,这肯定是一种可能性,但我的印象是 OP 只是没有得到 i * n + j
部分
+1 用于解释和指出 std::vector首先,你正在做的是将 1 添加到一维数组的不同槽中。
这是您的代码的注释版本:
int *a = new int[m*n]; // declares a pointer a, that points to a newly
// allocated space on the heap, for an array of size m*n.
for( int i = 0 ; i < m ; i++) // loop through m number of times
for ( int j = 0 ; j < n ; j++) // loop through n number of times PER m
a[i*n + j] = 1; // assigns 1 to a spot [i*n + j]
这就是你如何制作一个动态二维数组(换句话说,指向数组的指针数组):
const int sizeX = 10;
const int sizeY = 5;
int** arrayOfPointers = new int*[sizeX];
for(int i = 0; i < sizeX; i++)
arrayOfPointers[i] = new int[sizeY];
然后,您可以使用双循环(未测试)向该数组添加多个元素:
for(int i = 0 ; i < sizeY ; i++) // loop through all the rows
for (int j = 0 ; j < sizeX ; j++) // loop through all columns for row i
arrayOfPointers[i][j] = i*j; // assigns i*j to a spot at row i, column j
这是打印二维数组内容的方法:
for(int i = 0 ; i < sizeY ; i++)
for (int j = 0 ; j < sizeX ; j++)
cout << arrayOfPointers[i][j];
cout << endl; // go to the next line when the row is finished
【讨论】:
【参考方案3】:首先,让我指出,这不是一个二维数组,而是一个一维数组。可以看到int* a = new int[ m*n ]
为大小为m*n
的整数分配了一个数组。
要获得二维数组,您可以使用int** a = new int*[m]
。请注意此处使用的两个星号 (*
)。分配了数组的“第一个”维度后,您现在必须通过以下方式分配第二个维度:
for( int i = 0; i < m; i++ )
a[i] = new int[n];
之后,您可以遍历 m
和 n
并使用 a[i][j]
访问数组内容。
使用C++中的STL,可以通过二维向量得到二维数组,如下:
std::vector< std::vector<int> > array( rows,
std::vector<int>( columns ) );
这将分配一个包含整数的二维向量,rows
元素位于第一维,columns
元素位于第二维。这种用法有时会令人不悦,但std::vector
会为您管理内存,这可能很好。
【讨论】:
【参考方案4】:尽管 Paul R 说过并且我完全支持,但上面代码中的注释是错误的,您不能使用 a[m][n]
来正确寻址已分配为一维内存的数组。
如果你真的必须在不使用向量或数组等 C++ 标准容器的情况下工作,你可以做的就是分配整个块,然后将地址存储到行的开头
int** createTwoDimMatrix(unsinged int rows, unsigned int columns)
int** rowAdressTable = new int*[rows];
int* baseMemory = new int[rows*columns];
//fill the rowAddressTable
for(unsinged int r=1; r<rows; ++r)
rowAdressTable[r] = rowsAdressTable[r-1]+columns*sizeof(int)
return rowAdressTable;
但让我再说一遍:请考虑使用 C++ 容器
【讨论】:
【参考方案5】:对于内存而言,无论你拥有什么样的数组,它们都存储为一个内存块,这些可以可视化为一维数组。
在这个例子中,因为你想要一个 m
x n
数组你分配一个 m*n
大小的块。这种方式与其他方式的区别在于,现在您必须以 1d 的方式访问您的数组。
例如具有以下二维数组:
1 2 3
4 5 6
7 8 9
它将按如下方式存储在内存中:
1 2 3 4 5 6 7 8 9
我认为您可以看到这种模式:为了从您的二维数组中访问a[i][j]
,一维等价物将是a[i*dim+j]
,其中dim
是您的行的长度。
您访问数组的方式完全取决于您分配它的方式。为了能够以arr[i][j]
的身份直接访问您的元素,您必须按如下方式分配内存:
int **arr = new int *[n];
for (int i=0; i<n; i++)
arr[i] = new int [m];
这将创建一个n
xm
数组。
【讨论】:
【参考方案6】:动态就像 int *p = 新的 int [10][10] 然后 *(p+(i*noofcols)+j) 给出值
【讨论】:
以上是关于需要有关 C++ 中二维数组的动态内存分配的帮助的主要内容,如果未能解决你的问题,请参考以下文章