diferencia entre la asignación de memoria a la matriz 2D en 1 paso o fila por fila

3 minutos de lectura

cuál sería el impacto en el acceso a la matriz o en la asignación de memoria para estos dos casos:

1.

    int **arr;
    arr = malloc( sizeof(int) * row * column );

2.

    int **arr;
    arr = malloc( sizeof(*arr) * row);
    for(i=0; i<row; i++)
        arr[i] = malloc( sizeof( **arr) * column));

  • Creo que quieres decir malloc(row * column * sizeof(int));

    – Kninnung

    4 de julio de 2013 a las 19:44

  • si.. gracias por mencionar

    – usuario1660982

    4 de julio de 2013 a las 19:45

diferencia entre la asignacion de memoria a la matriz 2D
Hormiga

  • En primer lugar, el “impacto” es que su primer método está roto. No funcionará a través de un int ** puntero.

    Para asignar una matriz 2D de una sola vez como intenta hacerlo en su primer método, en realidad debe asignar una matriz 1D de tamaño suficiente

    int *arr = malloc( row * column * sizeof *arr );
    // Note: `int *`, not `int **`
    

    y realizar el acceso mediante el recálculo del índice manual, por ejemplo, en lugar de hacer arr[i][j] tu tienes que hacer arr[i * column + j].

    Intentando almacenar el puntero asignado en int **arr y luego acceda a su matriz como arr[i][j] simplemente dará lugar a bloqueos.

  • En segundo lugar, su segundo método está bien. Es solo que en el segundo método no es necesario que asigne la memoria de segundo nivel por múltiples independientes malloc llamadas Puede asignar toda la memoria de segundo nivel de una sola vez

    int **arr = malloc( row  * sizeof *arr );
    int *arr_data = malloc( row * column * sizeof *arr_data );
    

    y luego simplemente distribuya esa memoria de segundo nivel preasignada entre las filas

    for (i = 0; i < row; i++)
      arr[i] = arr_data + i * column;
    

    (Por supuesto, puede asignar las filas de forma independiente, si así lo desea. También funcionará. La razón por la que quería asignarlas de una sola vez es para ilustrar mejor la similitud entre el primer y el segundo enfoque, como se comenta a continuación).

Ahora, al observar estos dos métodos, puede ver fácilmente que ambos esencialmente hacen lo mismo. La única diferencia es que en el primer método encuentras el comienzo de la fila sobre la marcha calculando arr + i * column cada vez (tenga en cuenta que arr[i * column + j] es equivalente a (arr + i * column)[j]). En el segundo método, calcula previamente todos los comienzos de las filas utilizando el mismo arr_data + i * column y guárdelos para su uso posterior en una matriz separada de “índice de fila” arr.

Por lo tanto, básicamente se reduce al equilibrio entre el uso de la memoria (el primer método requiere menos memoria) y la velocidad (el segundo método es potencialmente, pero no necesariamente, más rápido). Al mismo tiempo, el segundo método admite la sintaxis “natural” para el acceso a matrices 2D: arr[i][j]mientras que en el primer método tiene que usar una sintaxis de acceso 1D más complicada con recálculo de índice.

  • Gracias @Andrey muy bien explicado. Entendí todo. No haré preguntas tan tontas ahora 🙂

    – usuario1660982

    4 de julio de 2013 a las 20:01


  • + Desconocía esta técnica para asignar memoria para 2D, ¡Gracias!

    –Grijesh Chauhan

    4 de julio de 2013 a las 20:04


¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad