web-dev-qa-db-fra.com

Créez dynamiquement un tableau de chaînes avec malloc

J'essaie de créer un tableau de chaînes en C en utilisant malloc. Le nombre de chaînes que le tableau contiendra peut changer au moment de l'exécution, mais la longueur des chaînes sera toujours cohérente.

J'ai essayé cela (voir ci-dessous), mais j'ai du mal, tous les conseils dans la bonne direction seront très appréciés!

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

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

En fin de compte, je veux pouvoir utiliser le tableau pour ce faire:

strcpy(orderedIds[0], string1);
strcpy(orderedIds[1], string2);
/* etc */
33
Chris

Vous devez affecter un tableau de pointeurs de caractères, puis, pour chaque pointeur, affecter suffisamment de mémoire pour la chaîne:

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...

Semble être un bon moyen pour moi. Bien que vous exécutiez de nombreux mallocs, vous affectez clairement de la mémoire à une chaîne spécifique et vous pouvez libérer un bloc de mémoire sans libérer l'intégralité du "tableau de chaînes".

54
MByD

Étant donné que vos chaînes sont toutes de longueur fixe (probablement au moment de la compilation?), Vous pouvez effectuer les opérations suivantes:

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

// Clear-up
free(orderedIds);

Une solution plus lourde, mais plus générale, consiste à attribuer un tableau de pointeurs et à les initialiser par puces pour pointer sur les éléments d'un tableau de support brut:

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);
6
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
sahaj

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

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

..

0
Roman