これが私のコードです:
printf("%s\n", "test1");
char c = '2';
char * lines[2];
char * tmp1 = lines[0];
*tmp1 = c;
printf("%s\n", "test2");
printf
コンソールに秒が表示されません。
質問: 私のコードの何が問題なのか誰か説明してもらえますか?
注:私は学ぼうとしていますC
:)
この行:
char * lines[2];
char
2 つのポインターの配列を宣言します。ただし、実際にはポインターを何かに初期化するわけではありません。そのため、後で*tmp1 = (char)c;
その文字をメモリ内のどこかに割り当てc
ます。おそらくアドレス 0 (つまりNULL
) でさえも割り当てますが、これは悪いことです。
解決策は、配列を配列の配列として作成することです。
char lines[2][30];
これは、行がそれぞれ 30 文字の 2 つの配列を持つことを宣言します。文字列には特殊な終了文字が必要なため、最大 29 文字の文字列を含めることができます。
2 番目の解決策は、文字列にメモリを動的に割り当てることです。
char *lines[2];
lines[0] = malloc(30);
lines[1] = malloc(30);
基本的に、これは上記の array-of-arrays 宣言と同じことを行いますが、メモリをヒープに割り当てます。
もちろん、単一の文字 (およびターミネータ) の単一の文字列が必要な場合は、アスタリスクを削除するだけでほぼ正解です。
char line[2]; /* Array of two characters, or a string of length one */
初期化されていない配列lines
。したがってlines[0]
、初期化されていないポインタです。でそれを逆参照すること*tmp1
は、まったくの未定義の振る舞いです。
これがあなたが望むものに対応するかもしれないし、しないかもしれない代替案です:
char lines[2];
char * tmp1 = lines; // or "&lines[0]"
*tmp = c;
または、もっと簡単に:
char lines[2] = { c, 0 };
lines
初期化されておらず、tmp1
初期化が間違っています。
そのはず:
char lines[2];
char * tmp1 = lines;
または、次のように言うこともできます。
char * tmp1 = &lines[0];
または、文字列の配列の場合:
char lines[2][30];
char * tmp1 = lines[0];
この線
char * lines[2];
2つのcharポインタの配列を作成します。しかし、それはメモリを割り当てません。それはメモリ内のポインタの単なる「ハンドル」または「名前」です。ポインタは有用なものを指していません。
次のいずれかを使用してメモリを割り当てる必要がありますmalloc()
。
char * lines = malloc(2);
または、コンパイラにメモリを割り当てるように指示します。
char lines[2];
0
注:使用する前に、文字列をバイトで終了することを忘れないでください。
char *lines[2];
: char ポインターの 2 つの要素の配列。
char *tmp;
: 文字へのポインター。
char *tmp = lines[0]
0
: 配列の配列要素内の値lines
が に転送されtmp
ます。これは自動配列であるため、 の値としてガベージが含まれますlines[0]
。
*temp
: ガベージ値を逆参照します。未定義の動作。
char * tmp1 = lines[0];
ここでは、char ポインターを宣言し、そのポインター値を line[0] に初期化します。これは、初期化されていない line 配列に格納されている最初の要素です。
現在、tmp は未知の場所を指しており、実際にはアクセスできません。あなたが
*tmp1 = (char)c;
セグメンテーション違反の原因となる無効なメモリ アドレスで操作しています。