Estoy haciendo algo tonto aquí y yo no puedo poner mi dedo sobre exactamente qué:

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

Y en main() hago lo siguiente:

double **dataA;
int dim = 10; 
init_data(&dataA, dim, dim);

Pero luego a la derecha después de que cuando trato de imprimir los datos que el programa se bloquea:

int i,j;
    for(i=0;i<dim;i++)
        for(j=0;j<dim;j++)
            printf("%d\n", dataA[i][j]);

Lo que me estoy perdiendo?

Gracias

  • He publicado mi respuesta, ¿podría usted por favor, compruebe si funciona?
InformationsquelleAutor JDS | 2012-07-13

6 Comentarios

  1. 6

    Usted está haciendo un par de errores en su punteros. Se pasa el &dataA a init_data, por lo que el tipo de argumento debe ser: ***el doble, en lugar de ** * haga doble. También es el primer malloc es la inicialización de un array de punteros, no una matriz de dobles, por lo que debe ser sizeof(double *) * dim_x. El siguiente código debe trabajar.

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

    Su primer bucle debe tener también la condición de k < dim_x en lugar de k < dim_y. No importa en el caso actual ya que ambas dimensiones son las mismas, pero podría causar problemas si ellos no lo eran. Finalmente, usted debe utilizar %f en lugar de %d en su printf, como dobles son almacenados en un formato diferente al de los enteros, y que es probable que obtener un galimatías en lugar de lo que usted quiere.

    • Ok, creo que ahora entiendo. Muchas gracias
  2. 1

    La dataA de main nunca se está inicializado. El puntero data que pasar a init_data inmediatamente se sobrescribe con un puntero devuelto por malloc.

    • Mi idea era inicializar con la función de operar en él. O no obtener inició en el tiempo?
    • Entonces usted necesita para hacer algo como *data = malloc ...
  3. 1

    Si quiero asignar memoria e inicializar un consejo, me gustaría:

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

    Así initiliaze su junta directiva, simplemente hacer:

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

    En su caso, utilizar las double en lugar de int.

  4. 1

    Que no se ajuste el valor de la dataA en main().

    Me iba a cambiar la definición de init_data para devolver el puntero a los datos nuevos. Algo como esto:

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

    Y, a continuación, en 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]);
  5. 1

    Que el código tiene varios problemas, la mayoría de los cuales puede ser fácilmente identificado por el giro de su compilador advertencias de seguridad.

    El primer problema es que init_data espera un double** como primer argumento, sin embargo, que está pasando una double*** (compare sus advertencias del compilador). Desde init_data es inicializar la memoria que es la asignación de sí mismo, como contraposición a la inicialización de un bloque de memoria que se asigna a otra parte, usted podría quitar ese primer argumento y devuelven un double** lugar.

    Está también la asignación de una cantidad insuficiente de memoria para data. Lo que quieren es suficiente memoria para dim_x cantidad de double*, no double. Usted puede lograr también con sizeof(*data) (tipo de *data es double*) en lugar de sizeof(double*).

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


    Ya que hay dim_x double*s en datos y dim_y doubles en el bloque de memoria apuntado por cada uno de estos double*s, su primer bucle se debe iterar hasta dim_x, y la segunda hasta dim_y.

    También, arrojando el resultado de malloc (fundición de una void*) en C es innecesario. Hay respuestas en este sitio que le dirá por qué es preferible que no.


    Otro problema tiene que ver con la printf especificador de formato. %d es para int, %f se utiliza para double (%lf cuando se utiliza scanf).

    Ahora si se agrega un código para free su memoria asignada y ejecutar el programa a través de algo como valgrind, vas a ver que no estamos haciendo nada malo en la memoria.

    El código de trabajo, se vería así:

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

    Primer error es que usted está pasando &dataA a la función init_data, sino en la función que está recibiendo ese valor como double ** debe ser double ***. Porque está pasando el puntero de una variable de tipo double **. Así init_data prototipo de función debe ser de la siguiente

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

    Segundo error está en la siguiente declaración

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

    Esta declaración debe ser como la siguiente

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

    Porque tenemos que actualizar la variable de puntero dataA. Así que vamos a ser capaces de mostrar en main función de control después de que sale de init_data función. Y también vamos a guardar puntero a una doble. Por lo que debe ser sizeof(double *)

    Actualización de su init_data función de la siguiente

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

Dejar respuesta

Please enter your comment!
Please enter your name here