本当にarrを割り当てる必要がありますか?
呼び出すか、別の配列を指すように設定することによりarr
、所有するメモリのブロックを指すように設定する必要があります。malloc
それ以外の場合は、アクセスできる場合とできない場合があるランダムなメモリアドレスを指します。
C では、 の結果をキャストすることmalloc
はお勧めできません1。これは不要であり、含めるのを忘れた場合やスコープ内 stdlib.h
にプロトタイプがない場合、エラーを隠すことができる場合があります。malloc
通常、malloc
呼び出しは次のように書くことをお勧めします
T *ptr = malloc(N * sizeof *ptr);
whereT
は使用してN
いる型であり、割り当てたいその型の要素の数です。 sizeof *ptr
は と同等sizeof (T)
であるため、 を変更した場合でも、呼び出し自体T
でその変更を複製する必要はありません。malloc
メンテナンスの頭痛が 1 つ減ります。
mallocを使用しなくても結果が得られます
宣言で明示的に初期化しないため、 の初期値arr
は不確定2です。有効な書き込み可能なアドレスに対応する場合と対応しない場合があるランダムなビット文字列が含まれています。無効なポインターを介して読み取りまたは書き込みを試行した場合の動作はundefinedです。つまり、コンパイラーは、ユーザーが何か危険なことをしていることを警告する義務を負いません。未定義の動作の考えられる結果の 1 つは、コードが意図したとおりに動作しているように見えることです。この場合、たまたま書き込み可能で、重要なものが何も含まれていないランダムなメモリ セグメントにアクセスしているように見えます。
私の 2 番目の疑問は、' 9 行目にエラーがあると予想しているのは、それが printf("%s",*arr); か何か。
%s
変換指定子は、printf
対応する引数が typechar *
であることを示してprintf("%s", arr);
いるため、正しいです。変換指定子を使用した場合は、そうです。演算子またはorなどの添字を使用%c
して逆参照する必要があります。 arr
*
printf("%c", *arr);
printf("%c", arr[i]);
また、コンパイラのドキュメントに有効な署名として明示的に記載されていない限り、 asとして定義しないでください。または代わりに 使用します。main
void main()
int main(void)
int main(int argc, char **argv)
void *
1. C++ では、明示的なキャストなしに他のポインター型に値を割り当てることができないため、C++ ではキャストが必要です
。 2. これは、ブロック スコープで宣言されたポインターに当てはまります。ファイル スコープ (関数の外部) またはstatic
キーワードで宣言されたポインターは、暗黙的に NULL に初期化されます。