Dynamisch een array van strings maken met malloc

Ik probeer een array van strings in C te maken met behulp van malloc. Het aantal strings dat de array kan bevatten kan tijdens runtime veranderen, maar de lengte van de strings zal altijd consistent zijn.

Ik heb dit geprobeerd (zie hieronder), maar heb problemen, alle tips in de goede richting worden zeer op prijs gesteld!

#define ID_LEN 5
char *orderedIds;
int i;
int variableNumberOfElements = 5; /* Hard coded here */
orderedIds = malloc(variableNumberOfElements * (ID_LEN + 1));

Uiteindelijk wil ik de array hiervoor kunnen gebruiken:

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

Antwoord 1, autoriteit 100%

U moet een array van char-pointers toewijzen en vervolgens voor elke pointer voldoende geheugen toewijzen voor de string:

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

Het lijkt me een goede manier. Hoewel u veel mallocs uitvoert, wijst u duidelijk geheugen toe aan een specifieke string en kunt u één blok geheugen vrijmaken zonder de hele “string-array” vrij te maken


Antwoord 2, autoriteit 9%

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]);
}

Antwoord 3, Autoriteit 8%

Aangezien uw snaren allemaal vaste lengte zijn (vermoedelijk op compile-time?), kunt u het volgende doen:

char (*orderedIds)[ID_LEN+1]
    = malloc(variableNumberOfElements * sizeof(*orderedIds));
// Clear-up
free(orderedIds);

Een meer omslachtig, maar meer algemene, oplossing, is om een ​​reeks aanwijzingen toe te wijzen, en psuedo-initialiseert ze om te wijzen op elementen van een RAW-backing-array:

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

Antwoord 4


#define ID_LEN 5
char **orderedIds;
int i;
int variableNumberOfElements = 5; /* Hard coded here */
orderedIds = (char **)malloc(variableNumberOfElements * (ID_LEN + 1) * sizeof(char));
..

Other episodes