二维数组作为连续的内存块
2D array as contiguous block of memory
我知道这个问题已得到解答,但不知何故对我不起作用。
我像这样为数组动态分配内存:
arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*columns*sizeof(int))); // <-- THIS DOESN'T WORK
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
//arr[row] = (int*)(malloc(columns*sizeof(int))); <---THIS WORKS
arr[row][col] = num;
printf("%d ", arr[row][col]);
if((++col == columns)){
row++;
col = 0;
printf("\n");
}
}
如果矩阵是 6x6,它会在第 4 行后抛出分段错误。
有什么建议吗?谢谢
编辑:
请参阅:http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/ 第 4 点。如果我按照第 3 点那样做,它就会起作用。但我需要它,就像 4 中那样。
您需要为每个 row
分配内存,而不仅仅是第一个 row
。替换
arr[0] = (int*)(malloc(rows*columns*sizeof(int)));
和
for(int i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
此处所做的更改是:
- 所有行都将分配
columns * sizeof(int)
字节的内存。
- 转换
malloc
的结果在 C 中毫无意义。我已将其删除。
您可能需要在循环中添加检查以防止溢出。像
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
固定代码为
int i, row = 0, col = 0;
int rows = 6, columns = 6; /* For 6x6 matrix */
arr = malloc(rows * sizeof(int*));
for(i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
arr[row][col] = num;
printf("%d ", arr[row][col]);
if(++col == columns){
row++;
col = 0;
printf("\n");
}
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
}
要分配连续内存,您必须使用
arr = malloc(sizeof(int *) * rows);
arrayData = malloc(sizeof(int) * columns * rows);
for(i = 0; i < rows; i++)
arr[i] = arrayData + i * columns ;
要解除分配,您需要
free( arrData );
free( arr );
见here
对于 6x6 矩阵,动态内存是多余的。你应该简单地使用:
int arr[rows][cols];
这更简单、更清晰、更快速、更不容易出错,而且总体上更安全——只要您将矩阵大小保持得足够小,以便轻松放入堆栈即可。如果您需要一个大矩阵(比如 1 MiB 以上,但您需要调整阈值以适应您的系统),那么动态内存是相关的。
您可以对 arr[0]
进行单一分配,但您必须对 arr[1]
到 arr[5]
中的每一个进行显式分配。我是这样做的:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int rows = 6;
int cols = 6;
int **arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*cols*sizeof(int)));
for (int i = 1; i < rows; i++)
arr[i] = arr[i-1] + cols;
printf("\nArray: \n");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
arr[i][j] = (i+1) * (cols + 1 - j);
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%3d", arr[i][j]);
putchar('\n');
}
free(arr[0]);
free(arr);
return(0);
}
示例输出:
Array:
7 6 5 4 3 2
14 12 10 8 6 4
21 18 15 12 9 6
28 24 20 16 12 8
35 30 25 20 15 10
42 36 30 24 18 12
运行valgrind
健康状况良好
在任何情况下您都应该像现在这样使用碎片化的 malloc 调用。这是一种广泛传播但不好且不正确的做法。正如您所指出的,它不会在相邻内存中为您提供真正的二维数组,而是零散的、缓慢的混乱。
如何正确执行此操作:
在标准C中,写
int (*arr)[rows][columns] = malloc (sizeof(*arr));
(*arr)[r][c] = something;
...
free(arr);
或者如果您更喜欢使用更易于阅读(但可能更难理解)的语法:
int (*arr)[columns] = malloc (sizeof(int[rows][columns]));
arr[r][c] = something;
...
free(arr);
在过时的 C 版本中,您必须编写 "mangled array":
int* arr = malloc(rows * columns * sizeof(*arr));
arr[r*c] = something;
...
free(arr);
我知道这个问题已得到解答,但不知何故对我不起作用。 我像这样为数组动态分配内存:
arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*columns*sizeof(int))); // <-- THIS DOESN'T WORK
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
//arr[row] = (int*)(malloc(columns*sizeof(int))); <---THIS WORKS
arr[row][col] = num;
printf("%d ", arr[row][col]);
if((++col == columns)){
row++;
col = 0;
printf("\n");
}
}
如果矩阵是 6x6,它会在第 4 行后抛出分段错误。 有什么建议吗?谢谢
编辑: 请参阅:http://www.geeksforgeeks.org/dynamically-allocate-2d-array-c/ 第 4 点。如果我按照第 3 点那样做,它就会起作用。但我需要它,就像 4 中那样。
您需要为每个 row
分配内存,而不仅仅是第一个 row
。替换
arr[0] = (int*)(malloc(rows*columns*sizeof(int)));
和
for(int i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
此处所做的更改是:
- 所有行都将分配
columns * sizeof(int)
字节的内存。 - 转换
malloc
的结果在 C 中毫无意义。我已将其删除。
您可能需要在循环中添加检查以防止溢出。像
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
固定代码为
int i, row = 0, col = 0;
int rows = 6, columns = 6; /* For 6x6 matrix */
arr = malloc(rows * sizeof(int*));
for(i = 0; i < rows; i++)
arr[i] = malloc(columns * sizeof(int));
printf("\nArray: \n");
while(fscanf(fp, "%d", &num) == 1) {
arr[row][col] = num;
printf("%d ", arr[row][col]);
if(++col == columns){
row++;
col = 0;
printf("\n");
}
if(row == rows)
{
puts("Matrix full; Exiting loop...");
break;
}
}
要分配连续内存,您必须使用
arr = malloc(sizeof(int *) * rows);
arrayData = malloc(sizeof(int) * columns * rows);
for(i = 0; i < rows; i++)
arr[i] = arrayData + i * columns ;
要解除分配,您需要
free( arrData );
free( arr );
见here
对于 6x6 矩阵,动态内存是多余的。你应该简单地使用:
int arr[rows][cols];
这更简单、更清晰、更快速、更不容易出错,而且总体上更安全——只要您将矩阵大小保持得足够小,以便轻松放入堆栈即可。如果您需要一个大矩阵(比如 1 MiB 以上,但您需要调整阈值以适应您的系统),那么动态内存是相关的。
您可以对 arr[0]
进行单一分配,但您必须对 arr[1]
到 arr[5]
中的每一个进行显式分配。我是这样做的:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
int rows = 6;
int cols = 6;
int **arr = (int**)(malloc(rows*sizeof(int*)));
arr[0] = (int*)(malloc(rows*cols*sizeof(int)));
for (int i = 1; i < rows; i++)
arr[i] = arr[i-1] + cols;
printf("\nArray: \n");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
arr[i][j] = (i+1) * (cols + 1 - j);
}
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
printf("%3d", arr[i][j]);
putchar('\n');
}
free(arr[0]);
free(arr);
return(0);
}
示例输出:
Array:
7 6 5 4 3 2
14 12 10 8 6 4
21 18 15 12 9 6
28 24 20 16 12 8
35 30 25 20 15 10
42 36 30 24 18 12
运行valgrind
健康状况良好
在任何情况下您都应该像现在这样使用碎片化的 malloc 调用。这是一种广泛传播但不好且不正确的做法。正如您所指出的,它不会在相邻内存中为您提供真正的二维数组,而是零散的、缓慢的混乱。
如何正确执行此操作:
在标准C中,写
int (*arr)[rows][columns] = malloc (sizeof(*arr));
(*arr)[r][c] = something;
...
free(arr);
或者如果您更喜欢使用更易于阅读(但可能更难理解)的语法:
int (*arr)[columns] = malloc (sizeof(int[rows][columns]));
arr[r][c] = something;
...
free(arr);
在过时的 C 版本中,您必须编写 "mangled array":
int* arr = malloc(rows * columns * sizeof(*arr));
arr[r*c] = something;
...
free(arr);