2012-07-13 79 views
1

我在这里做一些愚蠢的,我不能把我的手指上到底是什么:C编程初始化二维数组动态

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

我贴我的答案,请您检查是否正常工作? – cybertextron 2012-07-13 02:55:25

回答

6

你是在你的指针做了一些错误。您将& 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代替ķ< dim_y。在目前的情况下,这两个维度都是相同的,但如果不是这样,会引起问题。最后,您应该在printf中使用%f而不是%d,因为double以与整数不同的格式存储,并且您可能会得到乱码而不是您想要的。

+0

好吧,我想我现在明白了。非常感谢你 – JDS 2012-07-13 03:32:07

1

dataAmain永远不会被初始化。您传递给init_data的指针data立即被malloc返回的指针覆盖。

+0

我的想法是用该函数对它进行初始化,然后对其进行操作。还是不及时启动? – JDS 2012-07-13 02:51:39

+0

然后,你需要做一些像'* data = malloc ...' – 2012-07-13 02:54:50

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; 
} 

所以initiliaze您的主板,简单地做:

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

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]); 
1

您的代码有几个问题,其中大部分可以通过将您的编译器警告提升来轻松识别。

的第一个问题是,init_data需要一个double**,因为它是第一个参数,不过你传递一个double***(检查你的编译器警告)。由于init_data正在初始化它自己分配的内存,与初始化其他地方分配的内存块相反,您可以删除该第一个参数并返回double**

您还在为data分配不足的内存量。你想要的是足够的内存dim_x的数量double*,不是double。您也可以使用sizeof(*data)*data的类型为double*)而不是sizeof(double*)来实现。

data = malloc(sizeof(*data) * dim_x); 


由于有dim_xdouble* S IN数据和dim_ydouble S IN的存储器中的块所指向的每个这些double* S的,你的第一环路应当迭代到dim_x,和第二个至多dim_y

此外,在C中投入malloc(铸造void*)的结果是不必要的。在这个网站上有答案会告诉你为什么最好不要。


另一个问题与printf格式说明符有关。 %d用于int,%f用于double%lf当使用scanf时)。现在

如果代码添加到您的free分配的内存,并通过类似的valgrind 运行你的程序,你会发现你不再做任何事情在内存调皮。

工作代码是这样:

#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; 
} 
1

第一个错误是要传递&dataA的功能init_data,但在功能您收到该值作为double **它应该是double ***。因为您正在传递类型为double **的变量的指针。所以init_data函数原型应该是如下

void init_data(double ***data, int dim_x, int dim_y); 

第二个错误是在下面的statment

data = (double **) malloc(sizeof(double) * dim_x); 

这statment应该像如下

*data = (double **) malloc(sizeof(double *) * dim_x); 

因为我们必须更新指针变量dataA。这样我们就可以在控制出来init_data函数后在main函数中显示它。而且我们还将存储指向double的指针。所以它应该是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);   
     }  
    } 
}