Cree dinámicamente una matriz de cadenas con malloc


Estoy tratando de crear una matriz de cadenas en C usando malloc. El número de cadenas que el array tendrá puede cambiar en tiempo de ejecución, pero la longitud de las cadenas siempre será consistente.

He intentado esto (ver más abajo), pero estoy teniendo problemas, cualquier consejo en la dirección correcta será muy apreciado!

#define ID_LEN 5
char *orderedIds;
int i;
int variableNumberOfElements = 5; /* Hard coded here */

orderedIds = malloc(variableNumberOfElements * (ID_LEN + 1));

En última instancia, quiero ser capaz de utilizar la matriz para hacer esto:

strcpy(orderedIds[0], string1);
strcpy(orderedIds[1], string2);
/* etc */
Author: Chris, 2011-05-09

4 answers

Debe asignar una matriz de punteros char, y luego, para cada puntero asignar suficiente memoria para la cadena:

char **orderedIds;

orderedIds = malloc(variableNumberOfElements * sizeof(char*));
for (int i = 0; i < variableNumberOfElements; i++)
    orderedIds[i] = malloc((ID_LEN+1) * sizeof(char)); // yeah, I know sizeof(char) is 1, but to make it clear...

Me parece una buena manera. Aunque realice muchos mallocs, claramente asigna memoria para una cadena específica, y puede liberar un bloque de memoria sin liberar toda la "matriz de cadenas"

 44
Author: MByD,
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
2013-07-25 04:51:17
char **orderIds;

orderIds = malloc(variableNumberOfElements * sizeof(char*));

for(int i = 0; i < variableNumberOfElements; i++) {
  orderIds[i] = malloc((ID_LEN + 1) * sizeof(char));
  strcpy(orderIds[i], your_string[i]);
}
 5
Author: sahaj,
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
2011-05-09 11:11:27

Dado que sus cadenas son todas de longitud fija (presumiblemente en tiempo de compilación?), puede hacer lo siguiente:

char (*orderedIds)[ID_LEN+1]
    = malloc(variableNumberOfElements * sizeof(*orderedIds));

// Clear-up
free(orderedIds);

Una solución más engorrosa, pero más general, es asignar una matriz de punteros, y psuedo inicializarlos para apuntar a los elementos de una matriz de respaldo raw:

char *raw = malloc(variableNumberOfElements * (ID_LEN + 1));
char **orderedIds = malloc(sizeof(*orderedIds) * variableNumberOfElements);

// Set each pointer to the start of its corresponding section of the raw buffer.
for (i = 0; i < variableNumberOfElements; i++)
{
    orderedIds[i] = &raw[i * (ID_LEN+1)];
}

...

// Clear-up pointer array
free(orderedIds);
// Clear-up raw array
free(raw);
 5
Author: Oliver Charlesworth,
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
2011-05-09 11:21:08

#define ID_LEN 5
char **orderedIds;
int i;
int variableNumberOfElements = 5; /* Hard coded here */

orderedIds = (char **)malloc(variableNumberOfElements * (ID_LEN + 1) * sizeof(char));

..

 0
Author: Roman,
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
2011-05-09 11:23:53