我在做一些愚蠢的事情,我无法准确地指出:
void init_data(double **data, int dim_x, int dim_y) {
int i,j,k;
data = (double **) malloc(sizeof(double) * dim_x);
for (k = 0; k < dim_y; k++) {
data[k] = (double *) malloc(sizeof(double) * dim_y);
}
for (i = 0; i < dim_x; i++) {
for (j = 0; j < dim_y; j++) {
data[i][j] = ((double)rand()/(double)RAND_MAX);
}
}
}
在main()中,我执行以下操作:
double **dataA;
int dim = 10;
init_data(&dataA, dim, dim);
但是在那之后,当我尝试打印数据时,程序崩溃了:
int i,j;
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
printf("%d\n", dataA[i][j]);
我错过了什么?
由于
答案 0 :(得分:6)
你的指针犯了一些错误。您正在将&amp; dataA传递给init_data,因此参数类型应为*** double,而不是** double。你的第一个malloc也是初始化一个指针数组,而不是一个双精度数组,所以它应该是sizeof(double *)* dim_x。下面的代码应该有效。
void init_data(double ***data_ptr, int dim_x, int dim_y) {
int i,j,k;
double **data;
data = (double **) malloc(sizeof(double *) * dim_x);
for (k = 0; k < dim_x; k++) {
data[k] = (double *) malloc(sizeof(double) * dim_y);
}
for (i = 0; i < dim_x; i++) {
for (j = 0; j < dim_y; j++) {
data[i][j] = ((double)rand()/(double)RAND_MAX);
}
}
*data_ptr = data;
}
void main() {
double **dataA;
int dim = 10;
init_data(&dataA, dim, dim);
int i,j;
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
printf("%f\n", dataA[i][j]);
}
你的第一个循环也应该具有条件k < dim_x而不是k&lt; dim_y。在当前情况下并不重要,因为两个维度都相同,但如果不是,则会引起问题。最后,你应该在你的printf中使用%f而不是%d,因为双打的格式与整数不同,你可能会得到比你想要的更多的胡言乱语。
答案 1 :(得分:1)
来自dataA
的{{1}}永远不会被初始化。您传递给main
的指针data
会立即被init_data
返回的指针覆盖。
答案 2 :(得分:1)
如果我想分配内存并初始化一块电路板,我会:
int
main(int argc, char *argv[])
{
int xSize, ySize;
int **board;
xSize = ySize = 5;
printf("X: %u; Y: %u\n", xSize, ySize);
board = calloc(xSize, sizeof(int *));
printf("%p\n", board);
int **temp = board;
for (i = 0; i < xSize; i++)
{
board[i] = calloc(ySize, sizeof(int));
printf("%d %p\n", i, board[i]);
}
initializeBoard (board, xSize, ySize);
temp = board;
for (i = 0; i < xSize; i++)
{
free(*temp);
(temp)++;
}
free(board);
return 0;
}
因此,只需执行以下操作即可启用您的电路板:
void
initializeBoard (int **board, int xSize, int ySize)
{
int x, y;
printf("----\n");
for (x = 0; x < xSize; x++)
{
for (y = 0; y < ySize; y++)
{
printf("%3d", board[x][y]);
board[x][y] = 0;
}
printf("\n");
}
}
在您的情况下,请使用double
代替int
。
答案 3 :(得分:1)
您没有在main()中设置dataA的值。
我会更改init_data的定义以返回指向新数据的指针。像这样:
double ** init_data(int dim_x, int dim_y) {
{
int i,j,k;
double **data = (double **) malloc(sizeof(double) * dim_x);
for (k = 0; k < dim_y; k++) {
data[k] = (double *) malloc(sizeof(double) * dim_y);
}
for (i = 0; i < dim_x; i++) {
for (j = 0; j < dim_y; j++) {
data[i][j] = ((double)rand()/(double)RAND_MAX);
}
}
return data;
}
然后在main()
double **dataA = init_data(10, 10);
int i,j;
for(i=0;i<dim;i++)
for(j=0;j<dim;j++)
printf("%d\n", dataA[i][j]);
答案 4 :(得分:1)
您的代码有几个问题,其中大部分都可以通过编译警告来轻松识别。
第一个问题是init_data
期望double**
作为它的第一个参数,但是你传递double***
(检查编译器警告)。由于init_data
正在初始化它自己分配的内存,而不是初始化你在其他地方分配的内存块,你可以删除第一个参数并返回double**
。
您还为data
分配了不足的内存量。你想要的是dim_x
double*
,{em>不 double
的足够内存。您也可以使用sizeof(*data)
(*data
类型为double*
)而不是sizeof(double*)
来实现这一目标。
data = malloc(sizeof(*data) * dim_x);
由于数据中有dim_x
double*
个,而dim_y
s指向的内存块中有double
double*
,因此您的第一个循环应该是迭代到dim_x
,你的第二个到dim_y
。
此外,不需要在C中投射malloc
(投射void*
)的结果。这个网站上有答案可以告诉你为什么你不喜欢它。
另一个问题与printf
格式说明符有关。 %d
用于int
,%f
用于double
(使用%lf
时scanf
)。
现在,如果您将代码添加到free
已分配的内存并通过 valgrind 之类的程序运行程序,您将看到您不再在内存中做任何顽皮的事情。< / p>
工作代码如下:
#include <stdio.h>
#include <stdlib.h>
double** init_data(int dim_x, int dim_y) {
int i,j,k;
double **data = malloc(sizeof(*data) * dim_x); /* hoping not NULL */
for (k = 0; k < dim_x; k++) {
data[k] = malloc(sizeof(**data) * dim_y); /* hoping not NULL */
}
for (i = 0; i < dim_y; i++) {
for (j = 0; j < dim_y; j++) {
data[i][j] = ((double)rand()/(double)RAND_MAX);
}
}
return data;
}
int main(void)
{
double **dataA;
int i, j, dim = 10;
dataA = init_data(dim, dim);
for(i=0; i < dim; i++)
for(j=0; j < dim; j++)
printf("%f\n", dataA[i][j]);
for (i = 0; i < dim; i++)
free(dataA[i]);
free(dataA);
return 0;
}
答案 5 :(得分:1)
第一个错误是您将&dataA
传递给函数init_data
,但是在函数中,您接收的值为double **
,它应该是double ***
。因为你传递的是double **
类型变量的指针。因此init_data
函数原型应如下所示
void init_data(double ***data, int dim_x, int dim_y);
第二个错误在以下陈述中
data = (double **) malloc(sizeof(double) * dim_x);
此声明应如下所示
*data = (double **) malloc(sizeof(double *) * dim_x);
因为我们必须更新指针变量dataA
。因此,在main
函数控制出来后,我们将能够在init_data
函数中显示它。而且我们将存储指向双精度的指针。所以它应该是sizeof(double *)
更新您的init_data
功能,如下所示
void init_data(double ***data, int dim_x, int dim_y)
{
int i,j,k;
*data = (double **) malloc(sizeof(double *) * dim_x);
for (k = 0; k < dim_y; k++)
{
((*data) + k) = (double *) malloc(sizeof(double) * dim_y);
}
for (i = 0; i < dim_x; i++)
{
for (j = 0; j < dim_y; j++)
{
(((*data) +i) +j) = ((double)rand()/(double)RAND_MAX);
}
}
}