如何为多维数组动态分配内存 [英] How to dynamically allocate the memory for multi dimensional arrays
问题描述
这里,我尝试动态分配内存以创建多维。 所以我声明了一个指向指针的指针:
int ***array ;
并为变量数组
分配了内存array = (int***)malloc((sizeof(int) * 2));
这是我的代码!
void main(void)
{
int matrices, rows, columns;
int ***array;
printf("
HOW MANY MATRICES YOU TO CREATE ? : ");
scanf("%d",&matrices);
array = (int***)malloc((sizeof(int) * matrices));
printf("
HOW MANY ROWS YOU TO CREATE ? : ");
scanf("%d",&rows);
printf("
HOW MANY COLUMNS YOU TO CREATE ? : ");
scanf("%d",&columns);
for(int i = 1; i <= matrices; i++)
{
printf("
Enter %d - matrix! ",i);
for(int j = 1; j <= columns; j++)
{
for(int k = 1; k <= rows; k++)
{
printf("
Enter element [%d[%d] : ",j,k);
scanf("%d",&array[i][j][k]);
}
}
}
//printing two matrices elements!!!
for(int l = 1; l <= matrices; l++)
{
printf("
MATRIX - %d !!
",l);
for(int m = 1; m <= columns; m++)
{
for(int n = 1; n <= rows; n++)
{
printf("%d ",array[l][m][n]);
}
printf("
");
}
}
}
但当我尝试打印这两个矩阵的元素时,这里只显示两个矩阵的第二个矩阵元素,并且两个矩阵中的第一个元素都显示为‘0’。
示例:
输入:
第一个矩阵
1 2 3
4 5 6
第二矩阵
9 8 7
3 5 2
输出:
第一个矩阵
0 8 7
3 5 2
第二矩阵
0 8 7
3 5 2
我是新来这个网站的,有任何错误请评论!!
推荐答案
您不仅仅是因为意外而分段错误,而且是因为指针的大小不变。因此,在您应该为int**
分配int*
的位置进行分配时,您的分配大小不会受到影响(由于意外...)
您通常希望避免成为三星级程序员,但有时,就像在这种情况下,这是必需的。在为任何指针或指针到指针进行分配时,或者在本例中为指针到指针到指针进行分配时,请理解不涉及任何数组。
当您声明int ***array;
时,您声明了单个指针。然后,指针指向您分配的一块指针(类型为int**
)(保存其地址)。您根据用户的输入为int**
个指针的矩阵分配存储空间。
每个矩阵的类型都是int**
,因此您必须为每个矩阵分配一个包含rows
指针数的内存块。
最后,为每个矩阵中的每一行分配cols
个数int
(类型int*
)。
int
列,为每个矩阵分配每个行指针。
直观地看,您的分配和分配如下所示:
array (int***)
|
+ allocate matricies number of [Pointers]
|
+----------+
| array[0] | allocate rows number of [Pointers] for each matrix
+----------+ assign to each pointer in array block
| array[1] |
+----------+ array[2] (int**)
| array[2] | <======= +-------------+
+----------+ | array[2][0] |
| .... | +-------------+ allocate cols no. of [int]
| array[2][1] | for each allocated row pointer
+-------------+
| array[2][2] | <=== array[2][2] (int*)
+-------------+ +----------------+
| ... | | array[2][2][0] |
+----------------+
| array[2][2][1] |
+----------------+
| array[2][2][2] |
+----------------+
| ... |
为了始终保持每个分配的类型大小正确,只需使用取消引用的指针来设置类型大小。例如,在为array
(int***
)分配时,您将使用:
array = malloc (matrix * sizeof *array); /* allocate matrix int** */
为每个array[i]
分配时,应使用:
array[i] = malloc (rows * sizeof *array[i]); /* array[i] int** pointers */
最后,在为int
的每一块array[i][j]
的每一行分配时,您将使用:
array[i][row] = malloc (cols * sizeof *array[i][row]);
如果您始终使用取消引用指针来设置文字大小,则永远不会出错。
按照上图依次执行每个分配(并验证每个分配),您可以编写如下所示的分配和释放例程:
/* use dereferenced pointer for type-size */
array = malloc (matrix * sizeof *array); /* allocate matrix int** */
if (!array) { /* validate EVERY allocation */
perror ("malloc-array");
return 1;
}
for (int i = 0; i < matrix; i++) {
array[i] = malloc (rows * sizeof *array[i]); /* array[i] int** pointers */
if (!array[i]) { /* validate */
perror ("malloc-array[i]");
return 1;
}
for (int row = 0; row < rows; row++) {
/* allocate cols int per-row in each matrix */
array[i][row] = malloc (cols * sizeof *array[i][row]);
if (!array[i][row]) {
perror ("malloc-array[i][row]");
return 1;
}
}
}
根据用户输入的行数和列数分配矩阵数量的完整示例为:
#include <stdio.h>
#include <stdlib.h>
int main (void) {
int ***array = NULL,
matrix,
rows,
cols;
fputs ("no. of matricies: ", stdout);
if (scanf ("%d", &matrix) != 1) /* validate EVERY input */
return 1;
fputs ("no. of rows : ", stdout);
if (scanf ("%d", &rows) != 1) /* ditto */
return 1;
fputs ("no. of cols : ", stdout);
if (scanf ("%d", &cols) != 1) /* ditto */
return 1;
/* use dereferenced pointer for type-size */
array = malloc (matrix * sizeof *array); /* allocate matrix int** */
if (!array) { /* validate EVERY allocation */
perror ("malloc-array");
return 1;
}
for (int i = 0; i < matrix; i++) {
array[i] = malloc (rows * sizeof *array[i]); /* array[i] int** pointers */
if (!array[i]) { /* validate */
perror ("malloc-array[i]");
return 1;
}
for (int row = 0; row < rows; row++) {
/* allocate cols int per-row in each matrix */
array[i][row] = malloc (cols * sizeof *array[i][row]);
if (!array[i][row]) {
perror ("malloc-array[i][row]");
return 1;
}
}
}
/* fill matricies with any values */
for (int i = 0; i < matrix; i++)
for (int j = 0; j < rows; j++)
for (int k = 0; k < cols; k++)
array[i][j][k] = j * cols + k + 1;
/* display each matrix and free all memory */
for (int i = 0; i < matrix; i++) {
printf ("
matrix[%2d]:
", i);
for (int j = 0; j < rows; j++) {
for (int k = 0; k < cols; k++)
printf (" %2d", array[i][j][k]);
putchar ('
');
free (array[i][j]); /* free row of int (int*) */
}
free (array[i]); /* free matrix[i] pointers (int**) */
}
free (array); /* free matricies pointers (int***) */
}
(注意:在释放指向每个矩阵的指针块之前,先为int
的每个块释放内存,然后再为每个矩阵中的行指针块释放内存)
示例使用/输出
$ ./bin/allocate_p2p2p
no. of matricies: 4
no. of rows : 4
no. of cols : 5
matrix[ 0]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
matrix[ 1]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
matrix[ 2]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
matrix[ 3]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
内存使用情况/错误检查
在您编写的任何动态分配内存的代码中,您对分配的任何内存块负有2个责任:(1)始终为内存块保留指向起始地址的指针,以便(2)当不再需要它时,可以将其释放。
您必须使用内存错误检查程序来确保您不会尝试访问内存或写入所分配块的边界之外,不会尝试读取条件跳转或基于未初始化值进行条件跳转,并最终确认您释放了已分配的所有内存。
for Linuxvalgrind
是正常选择。每个平台都有类似的内存检查器。它们都很容易使用,只需运行您的程序即可。
$ valgrind ./bin/allocate_p2p2p
==9367== Memcheck, a memory error detector
==9367== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==9367== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==9367== Command: ./bin/allocate_p2p2p
==9367==
no. of matricies: 4
no. of rows : 4
no. of cols : 5
matrix[ 0]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
matrix[ 1]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
matrix[ 2]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
matrix[ 3]:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
==9367==
==9367== HEAP SUMMARY:
==9367== in use at exit: 0 bytes in 0 blocks
==9367== total heap usage: 23 allocs, 23 frees, 2,528 bytes allocated
==9367==
==9367== All heap blocks were freed -- no leaks are possible
==9367==
==9367== For counts of detected and suppressed errors, rerun with: -v
==9367== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
始终确认您已释放已分配的所有内存,并且没有内存错误。
过目一遍,如果您还有其他问题,请告诉我。
这篇关于如何为多维数组动态分配内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!