2012-07-13 5 views
1

여기 어리석은 일을하고 그리고 난 내 손가락을 넣어 수 없습니다 정확히 : C 프로그래밍 초기화 2 차원 배열 동적

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

그리고 주에서

() 나는 다음을 수행하십시오

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

다음과 같은 init_data 기능, 당신은 확인하십시오 수 있을까? – cybertextron

답변

6

당신은 당신의 포인터에서 몇 가지 실수를하고 있습니다. & dataA를 init_data에 전달하므로 인수 유형은 ** double 대신 *** double이어야합니다. 또한 첫 번째 malloc은 double 배열이 아닌 포인터 배열을 초기화하므로 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)를 대신 K < dim_y의 < dim_x 있어야한다. 두 가지 차원이 동일하기 때문에 현재의 경우에는 문제가되지 않지만 그렇지 않은 경우 문제가 발생할 수 있습니다. 마지막으로 printf에서는 % d 대신 % f를 사용해야합니다. double은 정수와 다른 형식으로 저장되기 때문에 원하는 것보다 횡설수설 할 수 있습니다.

+0

좋아, 이제 알 것 같아. 대단히 감사합니다. – JDS

1

main에서 dataA가 초기화되고 있지 않습니다. 포인터 datainit_data에 전달하면 즉시 malloc이 반환 한 포인터로 덮어 씁니다. 내가 메모리를 할당하고 보드를 초기화 할 경우

+0

제 아이디어는 그 함수로 초기화 한 다음 그것을 조작하는 것이 었습니다. 아니면 제 시간에 시작하지 않습니까? – JDS

+0

그런 다음'* data = malloc ... '과 같은 것을해야합니다. –

1

, 나는 것 : 귀하의 경우에는

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

을 대신 intdouble를 사용

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.

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

그리고()

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**을 기대하고 있다는 것입니다. 은 자신을 할당하는 메모리를 초기화하기 때문에 다른 곳에 할당 한 메모리 블록을 초기화하는 것과는 달리 첫 번째 인수를 제거하고 double**을 대신 반환 할 수 있습니다.

또한 data에 충분한 양의 메모리를 할당하고 있습니다. 원하는 것은 dim_x 양의 메모리가 double*, 이 아닌double입니다. sizeof(double*) 대신 sizeof(*data) (*data 유형은 double*)으로도 달성 할 수 있습니다. 데이터 dim_xdouble* S 및 dim_ydouble의 메모리의 블록에 있기 때문에

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


double* (S)의 각각에 의해, 첫 번째 루프에 제를 dim_x까지 반복되어야하고,에 지적 dim_y.

또한 malloc (캐스팅 a)의 결과를 캐스팅하지 않아도됩니다. 이 사이트에는 귀하가 원하지 않는 이유를 알려주는 답변이 있습니다.


또 다른 문제점은 printf 형식 지정자와 관련이 있습니다. %dint이고, %fdouble (scanf을 사용할 경우 %lf)에 사용됩니다.

이제 당신은 당신이 더 이상 메모리에 나쁜 아무것도하고있는 것을 볼 수 있습니다, 당신의 할당 된 메모리를 freeValgrind의 같은 것을 통해 프로그램을 실행하는 코드를 추가합니다.

#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

첫 번째 실수는 당신이 기능 init_data&dataA 전달되지만, 함수에서 당신이 double ***해야 double **로 그 값을받는 것입니다 : 같은

실무 코드가 보일 것이다. 변수가 double ** 인 포인터를 전달하고 있습니다.

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

을에 다음과 같이 그래서 init_data 함수 프로토 타입이어야한다 변수 dataA. main 기능으로 표시 할 수있게되기 때문에, 제어 후에는 init_data 기능이 나옵니다. 그리고 우리는 double에 대한 포인터를 저장할 것입니다. 그래서해야 sizeof(double *)

작동하는지 업데이트 내 대답을 게시

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