Heap asigna una matriz 2D (no una matriz de punteros)


Estoy escribiendo código C y me gustaría asignar un montón de 512*256 bytes. Para mi propia conveniencia me gustaría poder acceder a los elementos con el array de sintaxis[a] [b]; sin aritmética para encontrar el índice correcto.

Cada tutorial que veo en línea me dice que cree una matriz de punteros que apuntan a matrices de las filas que quiero en mi matriz. Esto significa que cada subarray necesita ser malloc d y libre había individualmente. Estoy interesado en una solución que solo requiere una llamada a malloc y una llamada gratis.(Por lo tanto, todos los elementos son contiguos) Creo que esto es posible porque no voy a construir una matriz dentada.

Agradecería que alguien pudiera compartir la sintaxis para declarar tal array.

Author: Paul, 2012-04-12

6 answers

Bien, si desea asignar una matriz de tipo, la asigna a un puntero de ese tipo.

Dado que las matrices 2D son matrices de matrices (en su caso, una matriz de 512 matrices de 256 caracteres), debe asignarla en un puntero a una matriz de 256 caracteres:

char (*arr)[256]=malloc(512*256);
//Now, you can, for example:
arr[500][200]=75;

(Los paréntesis alrededor de *arr son para que sea un puntero a la matriz, y no una matriz de punteros)

 38
Author: asaelr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-19 20:10:10

Si asigna la matriz de esta manera, requiere dos llamadas a free, pero permite la sintaxis de estilo array[a][b] y es contigua.

char **array = malloc(512 * sizeof(char *));
array[0] = malloc(512*256);
for (int i = 1; i < 512; i++)
    array[i] = array[0] + (256 * i);

Ver array2 aquí para más información: http://c-faq.com/aryptr/dynmuldimary.html

 14
Author: Matt Eckert,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-12 02:00:46

Esto es fácil asumiendo que no necesita compatibilidad con el antiguo estándar C89 (entre los compiladores de C actuales, solo MSVC y algunos compiladores de destino embebidos están al revés). Así es como lo haces:

int (*array)[cols] = malloc(rows * sizeof *array);

Entonces array[a][b] es válido para cualquier {[3] {} en[4]} y {[5] {} en[6]}.

En el lenguaje del estándar C, array tiene tipo variable modificado. Si desea pasar el puntero a otras funciones, deberá repetir este tipo en la lista de argumentos de la función y asegúrese de que al menos el número de columnas se pasa a la función (ya que es necesario como parte del tipo modificado de forma variable).

Edit: Me perdí el hecho de que OP solo se preocupa por un tamaño fijo, 512x256. En ese caso, C89 será suficiente, y todo lo que necesita es:

int (*array)[256] = malloc(512 * sizeof *array);

Se puede usar exactamente el mismo tipo en las listas de argumentos de función si necesita pasar el puntero entre funciones (y también como un tipo de retorno de función, pero para este uso es posible que desee escribirlo... :-)

 12
Author: R..,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-12 02:46:18

Dado que conoce el tamaño de la matriz antes de tiempo, podría crear un tipo struct que contenga una matriz 521x256, y luego asignar dinámicamente la struct.

 5
Author: trutheality,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-12 01:56:55

Si conoce el tamaño de la matriz, puede typedef y hacer un puntero a ella. Aquí hay un breve fragmento de código que demuestra este uso:

#include <stdio.h>
#include <stdlib.h>

typedef int array2d[20][20];

int main() {
    int i,j;
    array2d *a = malloc(sizeof(array2d));
    for(i=0;i!=20;i++)
        for(j=0;j!=20;j++)
            (*a)[i][j] = i + j;

    for(i=0;i!=20;i++)
        for(j=0;j!=20;j++)
            printf("%d ",(*a)[i][j]);
    free(a);
    return 0;
}
 2
Author: dasblinkenlight,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-12 02:00:43

es posible asignar dinámicamente el mismo tipo de matriz multidimensional que

static char x[512][256];

Te da, pero es un poco complicado debido a la descomposición del tipo. Sólo sé cómo hacerlo con un typedef:

typedef char row[512];
row *x = malloc(sizeof(row) * 256);

Esto solo le permite determinar el tamaño de la segunda dimensión en tiempo de ejecución. Si ambas dimensiones pueden variar en tiempo de ejecución, necesita un vector dope.

 2
Author: zwol,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-12 02:01:23