0

Cで文字列を割り当てる際に正しい形式はどれですか?

char *sample;

sample = malloc ( length * sizeof(char) );

また

sample = malloc ( length * sizeof(char*) );

1バイトかかるchar*のに4バイトかかるのはなぜですか?char

4

9 に答える 9

6

目標が文字列を格納することであると仮定するとlength、正しい割り当ては次のようになります。

sample = malloc(length + 1);

ノート:

  1. は使用しないでくださいsizeof (char)。常に 1 であり、値を追加しません。
  2. ターミネータを思い出してください。(名前に基づいて) ターミネータlengthは、文字列の表示可能な文字の長さであると想定しました。つまり、 の戻り値はstrlen()になりますlength
  3. あなたがそうしなかったことは知っていますが、からの戻り値のキャストmalloc()もすべきではないことを指摘する価値があります。

大きい理由char *は、ポインター型であり、ポインターはほとんどの場合、1 文字よりも大きいためです。多くのシステム (あなたのシステムなど) では、それらは 32 ビットですが、文字はわずか 8 ビットです。ポインタはマシンのメモリ内の任意のアドレスを表すことができる必要があるため、より大きなサイズが必要です。64 ビット コンピュータでは、ポインタは多くの場合 64 ビット、つまり 8 文字です。

于 2012-12-06T11:11:18.877 に答える
2

char が 1 バイトかかるのに、char* が 4 バイトかかるのはなぜですか?

32 ビット システムを使用しているため、ポインターは 4 バイト必要です。char*ポインタです。

char常に正確に 1 バイトを使用するため、次のように掛ける必要はありませんsizeof(char)

sample = malloc (length);

lengthnull 終了のためにすでにパディングされていると想定しています。

于 2012-12-06T11:12:26.003 に答える
1
sample = malloc(length);

正しいものです

char*はポインタであり、ポインタは4バイトを使用します(たとえば、32ビットプラットフォームの場合)

charはcharであり、charは1バイトを使用します

于 2012-12-06T11:10:06.630 に答える
1
sample = malloc ( length * sizeof(char) );

length文字数にメモリを割り当てたい場合は、最初が正しいものです。

char*プラットフォームではたまたま 4 バイトのポインタ型です。したがって、sizeof(char*)4 が返されます。

ただしsizeof(char)、常に 1 であり、smae は C 標準で保証されています。

于 2012-12-06T11:10:47.020 に答える
1

あなたの場合、長さ文字の配列を割り当てたいとします。指しているサイズのsample倍数の配列へのポインターに格納します。lengthsizeof(char*)へのポインタのサイズですchar。のサイズではありませんchar

良い習慣は

sample = malloc(length * sizeof(*sample));

それを使用して、ポイントしたいもののサイズの長さを予約します。これにより、サンプルを別の種類のデータとして宣言するだけで、いつでもデータ型を変更できます。

int *sample;

sample = malloc(length * sizeof(*sample)); // length * 4


char *sample;

sample = malloc(length * sizeof(*sample)); // length * 1
于 2012-12-06T11:35:00.160 に答える
1

既にnullengthターミネータのアカウントがある場合、次のいずれかを記述します。

sample = malloc(length);

また:

sample = malloc(length * sizeof(*sample));

sizeof(char*)はポインターのサイズであり、割り当てられたバッファーに必要なサイズとはまったく関係ありません。だから絶対に使わないでください。

私の最初のスニペットは、文字列操作コードには十分な IMO です。C プログラマーは、C のメモリと文字列の長さがどちらも の倍数で測定されることを知っていますsizeof(char)。誰もが常に知っている変換係数をそこに入れる必要はありません1

私の 2 番目のスニペットは、一般的に割り当てを記述する唯一の正しい方法です。したがって、すべての割り当てに一貫性を持たせたい場合は、文字列の割り当てでもそれを使用する必要があります。すべての割り当てが一貫しているように見える理由として、次の 2 つが考えられます (どちらも IMO はかなり弱いですが、実際には間違っているわけではありません)。

  • 1 つの視覚的パターンだけを認識する方が読みやすいと感じる人もいます。
  • 将来、ワイド文字列を処理するコードの基礎としてこのコードを使用することをお勧めします。一貫したフォームをlength使用すると、バイト単位ではなくワイド文字単位で測定されたときに適切な割り当てを取得することが思い出されます。一貫した形式として使用するということは、が測定される単位と同時にsizeof(*sample)の型を更新すると仮定すると、そのコード行をまったく変更する必要がないことを意味します。samplelength

その他のオプションは次のとおりです。

sample = calloc(length, 1);
sample = calloc(length, sizeof(char));
sample = calloc(length, sizeof(*sample));

ここではおそらくかなり無意味ですが、メモリをゼロにすることの些細な二次的効果と同様に、使用する予定のオブジェクトの数とサイズを明示的に分離するのに対し、合計サイズが必要なだけでcallocあるという興味深い違いがあります。 .mallocmalloc

于 2012-12-06T11:36:16.983 に答える
1

特定のケースでは、次の 2 つの異なることを行っています。

最初のケースでは:sample = malloc ( length * sizeof(char) );

1バイトlengthのタイプのサイズを掛けて割り当ててcharいます

2番目のケースでは: sample = malloc ( length * sizeof(char*) );

マシン上で4バイトlengthのポインタのサイズを掛けて割り当ててい ます。char

ケース 1 は不変のままですが、2 番目のケースではサイズが可変であると考えてください。

于 2012-12-06T11:14:05.750 に答える
0

どのタイプの場合でもT、通常の形式は

T *p = malloc(N * sizeof *p);

また

T *p;
...
p = malloc(N * sizeof *p);

ここで、は割り当てたいNタイプの要素の数です。T式の*pタイプTは、であるため、sizeof *pと同等sizeof (T)です。

sizeofこれは、またはのような演算子であり、ライブラリ関数ではないことに注意してください。括弧は、オペランドがまたはのような型名である場合にのみ必要です。 &*intchar *

于 2012-12-06T11:59:50.230 に答える