¿Cómo asigno dinámicamente una matriz de cadenas en C?

4 minutos de lectura

Si tengo la cantidad de elementos en una var llamada “totalstrings” y una var llamada “string size” que es el tamaño de la cadena de cada elemento, ¿cómo asigno dinámicamente una matriz llamada “matriz?”

Esta es una matriz de cadenas en C, no en C++.

¡Gracias!

  • Depende de lo que haya intentado y lo que no funcionó.

    – usuario703016

    4 oct 2011 a las 18:21

  • Y, por supuesto, por qué crees que no funcionó.

    – Pete Wilson

    4 oct 2011 a las 18:30

avatar de usuario
mah

NOTA: Mis ejemplos no están comprobando los retornos NULL de malloc()… aunque deberías hacerlo; se bloqueará si intenta usar un puntero NULL.

Primero debe crear una matriz de punteros char, uno para cada cadena (char *):

char **array = malloc(totalstrings * sizeof(char *));

A continuación, debe asignar espacio para cada cadena:

int i;
for (i = 0; i < totalstrings; ++i) {
    array[i] = (char *)malloc(stringsize+1);
}

Cuando haya terminado de usar la matriz, debe recordar free() cada uno de los punteros que has asignado. Es decir, recorrer la matriz llamando free() en cada uno de sus elementos, y finalmente free(array) así como.

  • Pero malloc De todos modos, devolver NULL suele ser un error demasiado grave para continuar. No queremos ser demasiado paranoicos, ¿verdad? Y lo que realmente está mal es el elenco de malloc, que en C es completamente innecesario y, por lo general, es una mala práctica (pero no importa, también vengo de un entorno de C ++). De lo contrario, buena respuesta. +1 por recordar correctamente free.

    – Christian Raú

    4 oct 2011 a las 18:34


  • De hecho, en C, convertir malloc result puede ser peligroso si uno olvida incluir . Buena respuesta de lo contrario.

    – Sergo Pasoevi

    5 de enero de 2016 a las 14:18

  • ¿Qué pasa si cada cadena tiene un tamaño diferente, digamos, estoy tratando de almacenar una lista de nombres

    – Adishri

    28 de octubre de 2016 a las 5:24

  • @Aadishri eso no es un problema; no necesita que cada malloc de cadena tenga el mismo tamaño, puede dimensionarlos como lo necesite.

    – mah

    8 de noviembre de 2016 a las 20:21

  • @sivaram, debe tener al menos un número inicial de cadenas para comenzar, y querrá mantener una variable con el tamaño actual de su matriz. Si más adelante necesita ampliar el espacio, puede realloc() su matriz a un tamaño mayor.

    – mah

    25 de julio de 2018 a las 13:25

El idioma común para asignar una matriz N por M de cualquier tipo T es

T **a = malloc(N * sizeof *a);
if (a)
  for (i = 0; i < N; i++)
    a[i] = malloc(M * sizeof *a[i]);

A partir del estándar de 1989, no es necesario convertir el resultado de mallocy de hecho hacerlo se considera una mala práctica (puede suprimir un diagnóstico útil si olvida incluir stdlib.h o si no tiene un prototipo para malloc en alcance). Las versiones anteriores de C tenían malloc regreso char *, por lo que el elenco era necesario, pero las probabilidades de que tengas que trabajar con un compilador anterior a 1989 son bastante remotas en este punto. C++ lo hace requiere el elenco, pero si está escribiendo C ++, debería usar el new operador.

En segundo lugar, tenga en cuenta que estoy aplicando el sizeof operador al objeto que se está asignando; el tipo de expresión *a es T *y el tipo de *a[i] es T (donde en su caso, T == char). De esta manera, no tiene que preocuparse por mantener el sizeof expresión sincronizada con el tipo de objeto que se asigna. OIA, si decides usar wchar en lugar de charsolo necesitas hacer ese cambio en un solo lugar.

char** stringList = (char**)malloc(totalStrings * sizeof(char*));

for( i=0; i<totalStrings; i++ ) {
  stringList[i] = (char*)malloc(stringSize[i]+1);
}

avatar de usuario
Zurakin

Sé que esta pregunta es antigua y ya fue respondida. Solo quiero señalar que malloc es una llamada al sistema y no debe usarse varias veces.

Sería mejor asignar una gran parte de la memoria y hacer que la matriz apunte a ella. Algo como esto :

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

#define STR_SIZE 100 //STR_SIZE doesn't have to be a constant

int main(){
        int i;
        char **arr;
        char *long_string;
        long_string = (char *)malloc(sizeof(char)*STR_SIZE*10);
        arr = malloc(sizeof(char *)*10);

        //Pointing each item of the array to an allocated memory. 
        for (i=0; i<10; i++){
                arr[i] = (long_string + STR_SIZE * i);
        }

        //Initialising the array
        for (i=0; i<10; i++){
                strcpy(arr[i], "This is a line in a\
 paragraph\n");
        }

        //Printing the items of the array
        for (i=0; i<10; i++){
                printf("%s \n", arr[i]);
        }

        //freeing the allocated memory
        free(long_string);
        free(arr);

        return 0;
}

avatar de usuario
pete wilson

Bueno, primero es posible que desee asignar espacio para “matriz”, que sería una matriz de char * que es “totalstrings” de largo.

¿Cuáles serían entonces los índices inicial y final en “matriz”? Sabes que el primero es 0; cual es el ultimo

Luego, para cada entrada en “matriz”, podría (si quisiera) asignar un área de memoria que sea “stringsize+1” (¿por qué +1, dígame por favor?) de largo, poniendo la dirección inicial de esa área — esa cadena, en el miembro correcto de “matriz”.

Eso sería un buen comienzo, en mi opinión.

¿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