web-dev-qa-db-ja.com

mallocを使用して文字列の配列を動的に作成する

mallocを使用してCで文字列の配列を作成しようとしています。配列が保持する文字列の数は実行時に変更できますが、文字列の長さは常に一定です。

私はこれを試みましたが(以下を参照)、問題があります。正しい方向のヒントは大歓迎です!

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

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

最終的には、これを行うために配列を使用できるようにしたいです。

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

Charポインターの配列を割り当ててから、ポインターごとに文字列に十分なメモリを割り当てます。

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

私にとっては良い方法のようです。多くのmallocを実行しますが、特定の文字列にメモリを明確に割り当て、「文字列配列」全体を解放せずに1ブロックのメモリを解放できます。

54
MByD

文字列がすべて固定長であると仮定すると(おそらくコンパイル時に?)、次のことができます。

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

// Clear-up
free(orderedIds);

より面倒ですが、より一般的な解決策は、ポインターの配列を割り当て、それらを生のバッキング配列の要素を指すように疑似初期化することです。

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