int i, j;
double **PNow, **PNext, *Array2D1, *Array2D2;
//Allocate memory
PNow = (double**)malloc(3 * sizeof(double*));
PNext = (double**)malloc(3 * sizeof(double*));
Array2D1 = (double*)malloc(5 * sizeof(double));
Array2D2 = (double*)malloc(5 * sizeof(double));
//Create 2-Dimensionality
for(i = 0; i < 3; i++)
{
PNow[i] = Array2D1 + i * 5;
PNext[i] = Array2D2 + i * 5;
};
//Define Element Values
for(i = 0; i < 3; i++)
{
for(j = 0; j < 5; j++)
{
PNow[i][j] = 10.*(i + j);
PNext[i][j] = 1000.*(i + j);
};
};
//Output two matrices side-by-side.
for(i = 0; i < 3; i++)
{
for(j = 0; j < 5; j++)
{
printf("%6lg", PNow[i][j]);
if(j == 4)
{
printf("|");
};
};
for(j = 0; j < 5; j++)
{
printf("%6lg", PNext[i][j]);
if(j == 4)
{
printf("\n");
};
};
};
我的问题是第一个矩阵(PNow)结果如我所料,但由于某种原因,PNext中的一半值是PNow的值,我不能为我的生活弄清楚为什么它是这样做?我显然错过了一些东西..而且我对“Array2D1 + i * 5”正在做什么以及如何使PNow成为二维数组并不过分清楚?
任何帮助都会非常感激。 谢谢。
P.S。这是我得到的输出,所以你可以看到我的意思:
0 10 20 30 40| 20 30 40 50 20
10 20 30 40 50| 30 40 50 60 5000
20 30 40 50 60| 2000 3000 4000 5000 6000
答案 0 :(得分:2)
在C中你没有强制转换mallocs的结果,所以你的malloc行应该是
PNow = malloc(3*sizeof(double*));
您的问题是,您实际上并未在Array2D1
和Array2D2
中分配足够的内存。当您移过阵列中的第一个“行”时,您将超出分配的内存!所以你处于未定义的行为领域。在你的情况下,看起来你的两个矩阵相互重叠(虽然我的测试只是抛出一个错误)。您可以通过两种方式解决此问题:
在malloc中指定矩阵的完整大小,并按照以下方式执行:
Array2D1 = malloc(15*sizeof(double));
Array2D2 = malloc(15*sizeof(double));
或者在for循环中使用malloc:
for(i=0; i<3; i++){
PNow[i] = malloc(5*sizeof(double));
PNext[i] = malloc(5*sizeof(double));
}
编辑:关于每个例子中的释放主题
对于第一个例子,释放是直截了当的
free(PNow);
free(PNext);
free(Array2D1);
free(Array2D2);
对于第二个,您必须遍历每一行并单独释放
for (i = 0; i < 3; i++) {
free(PNow[i]);
free(PNext[i]);
}
Edit2:实际上,如果您要使用预处理器宏对行和列进行硬编码,那么就没有理由使用malloc。你可以这样做:
#define ROW 3
#define COL 5
double PNow[ROW][COL], PNext[ROW][COL];
Edit3:至于Array2D1 + i * 5
正在做什么,PNow
是一个指针数组,Array2D1
是一个指针。通过添加i * 5
,您将指针递增i * 5
(即,说“给我一个指向i * 5
的内存的指针,距Array2D1
一倍。”所以,你正在为PNow
填充指向行的适当大小的内存块的开头的指针。
答案 1 :(得分:0)
您的代码没有2D数组,也就是矩阵。你的指针也不能指向这样的对象。
可以指向2D数组的正确指针将声明为:
2016-06-03 21:00:14 > user1 has connected.
2016-06-03 21:00:22 > foobar disconnected.
2016-06-03 21:00:22 > foobar disconnected.
2016-06-03 21:00:29 > user2 has connected.
2016-06-03 21:00:29 > user2 has disconnected.
2016-06-03 21:00:30 > user2 has disconnected.
2016-06-03 21:00:30 > user2 has disconnected.
分配是直截了当的:
#define ROWS 4
#define COLS 5
double (*arr)[COLS];
删除类似内容:
arr = malloc(sizeof(*arr) * ROWS);
索引就像:
free(arr);
请注意相同的语法。语义不同。
没有必要也不需要手工制作的指针数组。
上面的代码显示了另一个重要规则:不要使用魔术值。请改用类似常量的宏。这些应该在代码的开头或配置部分arr[row][col]
(通常位于文件顶部附近或不同的头文件)。所以,如果你稍后改变,例如维度的长度,您不必编辑您明确写入的所有位置,而只需更改宏一次。
虽然上面的代码使用常量,但您也可以使用维度的变量。这是标准C,称为可变长度数组(VLA)。如果将数组传递给其他函数,则必须将它们作为附加参数传递:
#defined
请记住,数组参数会衰减到指向第一个元素的指针,因此void f(size_t rows, size_t cols, double a[rows][cols]);
实际上与上面的a
相同。最外层的尺寸可以省略,但是无论如何你都需要它,文档也可以指定它。