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

そして 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]);

私は何が欠けていますか?

ありがとう

4

6 に答える 6

9

あなたはポインタでいくつかの間違いを犯しています。を に渡している&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 < dim_x代わりに条件も必要ですk < dim_y。両方のディメンションが同じであるため、現在のケースでは問題ありませんが、そうでない場合は問題が発生します。最後に、double は整数とは異なる形式で格納され、必要なものではなく意味不明になる可能性があるため、%fの代わりに%dを使用する必要があります。printf

于 2012-07-13T02:56:07.690 に答える
1

最初の間違いは、関数に渡そ&dataAうとしていることですが、関数では、本来あるべきinit_data値を受け取っています。タイプの変数のポインタを渡しているためです。したがって、関数プロトタイプは次のようになりますdouble **double ***double **init_data

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

2番目の間違いは以下のステートメントにあります

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

このステートメントは次のようになります

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

ポインタ変数を更新する必要があるためですdataAmain制御が機能しなくなった後、機能して表示できるようにしinit_dataます。また、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);         
        }     
    } 
} 
于 2012-07-13T10:22:18.547 に答える
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

于 2012-07-13T02:52:43.880 に答える
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]);
于 2012-07-13T02:55:13.193 に答える
1

dataAfromが初期化されることはmainありません。data渡したポインタinit_dataは、 によって返されたポインタですぐに上書きされmallocます。

于 2012-07-13T02:50:47.747 に答える
1

コードにはいくつかの問題がありますが、その大部分は、コンパイラの警告を上げることで簡単に特定できます。

最初の問題は、最初の引数としてa をinit_data期待することですが、 a (コンパイラの警告を確認してください)を渡しています。他の場所に割り当てたメモリのブロックを初期化するのではなく、それ自体が割り当てているメモリを初期化しているため、その最初の引数を削除して代わりに a を返すことができます。double**double*** init_datadouble**

また、 に十分な量のメモリを割り当てていませんdata。必要なのは、 ではなくdim_x、 の量に十分なメモリです。の代わりに(type of is )でも実現できます。double* doublesizeof(*data)*datadouble*sizeof(double*)

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


dim_x double*data には がありdim_y double、これらの のそれぞれが指すメモリ ブロックには があるためdouble*、最初のループは まで反復しdim_x、2 番目のループは まで反復する必要がありますdim_y

また、Cでmalloc(casting a ) の結果をキャストする必要はありません。void*このサイトには、そうしない方がよい理由を説明する回答があります。


もう 1 つの問題は、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;
}
于 2012-07-13T03:13:59.117 に答える