- ベストアンサー
C言語の変数について
- C言語の変数について教えていただきたいです。バイト数制限はないのでしょうか?
- C言語で変数にバイト数制限はないのかについて教えてください。
- C言語で変数のバイト数制限について教えてください。
- みんなの回答 (6)
- 専門家の回答
質問者が選んだベストアンサー
このソースだと、 Aのポインタは、NULLで初期化後に、コマンドライン引数1のポインタをセット。 Bのポインタ(格納するメモリーの場所)は、NULLで初期化 Bのポインタをtest()関数に引き渡し (なのに、test()側では、それをポインタのポインタで受取り) そのNULLの位置は格納場所として確保されていないので"ABCD"をコピーした時点で、セグメントエラー。(コンパイラやOS次第だけど) なので、 A,Bにはバイト数制限はありますか? という問いついては、 ・Aは、コマンドライン引数の1つ目を示すargv[1]をポインタを使っていて これは、実行時に自動でメモリー確保されているので、 バイト数制限は、コマンドライン実行時の引数1の文字の長さということになります。 ・Bは、そもそもメモリーが確保されていないので、1バイトさえない、ということになります。 なお、 10行目 test( B ); ↓ test( &B ); 16行目 strcpy(B,"ABCD" ); ↓ *B = malloc(strlen("ABCD")+1); strcpy ( *B , "ABCD"); もしくは、1行で *B = strdup("ABCD"); と、メモリーを確保してからコピーするようにすれば、Bにバイト制限はなくなります。
その他の回答 (5)
- teuaitou
- ベストアンサー率32% (10/31)
AもBもcharポインターを宣言しているだけです。データを格納する領域は確保されてませんから、バイト数の制限などあるわけ無いですよ。 ポインターって理解されたますか?メモリ上の点(アドレス)を指し示すだけの機能しか無いですよ。なので、ポインタ変数を宣言すると、そのアドレスを格納するための領域しか確保されないですよ。そして、初期化して無けれなそのポインタ変数の内容は不定値です。
お礼
ご回答ありがとうございます。 すみません、ポインタの理解があまりできておらず稚拙な質問をしてしまいました。
- Wap58
- ベストアンサー率33% (29/87)
訂正、Apple LLVM version 7.3.0 (clang-703.0.31) ./a.out Q これで動きますね、スンマセン #include <stdio.h> #include <string.h> void test(char *B){ printf("test %s\n",B); if(B != NULL){ strcpy(B,"QQQQQQQQQQQQQQQQQQQQQQQQQQQQQ"); printf("strcpy %s\n",B); } } int main(int argc,char *argv[]){ char *A = NULL; A = argv[1]; printf("main %s\n",A); test(A); return 0; }
- Wap58
- ベストアンサー率33% (29/87)
文脈から自然解釈しました、間違えてたらスルーして *argv[]は配列のポインタを受け取ります char argv[] = "AAA_1BBB_2CCC_3";<=これのポインタ 配列は初期化の時のみメモリーを自動で確保します #include <stdio.h> void test(char *B){ printf("%s\n",B); } int main( int argc, char *argv[] ){ char *A = NULL; A = argv[1]; printf("%s\n",A); test(A); return 0; }
お礼
Aに関しては、領域が確保されているargのポインタを設定しているため、 正常に使えているということですね。 ありがとうございます。
- chie65536(@chie65535)
- ベストアンサー率44% (8740/19838)
C言語の「メモリ管理」は、基本的に「プログラマが自分で行なう」事になります。 言語そのものは「指示されたアドレスに、有効なメモリが存在するかどうか、一切、関知しない」のです。 例えば「5バイト分しか無い場所に8バイト書き込む処理」をしても、そのまま「警告無しに動作」します(そして「メモリを壊す」でしょう) 例えば「ROM領域になっていて、書き込みが出来ないメモリに書き込む処理」をしても、そのまま「警告無しに動作」します(そして「不正なメモリアクセス」の実行時例外が起きるでしょう) なので「そこに書き込めるメモリがあるかどうか?」や「何バイト分の書き込めるメモリがあるのか?」は「プログラムを書く人が自分で管理しないといけない」のです。 C言語が「OSそのものや、デバイスドライバの開発言語になっている理由」は「メモリの管理を自分で行なえるから」です。言い換えると「どこのメモリであっても自由に読み書き可能だから」なのです。
お礼
なるほど。 やはり私の記述では領域を確保していないため、メモリを壊している(想定外の領域を使用している。)ということですね。 ありがとうございます。
- asuncion
- ベストアンサー率33% (2127/6289)
私のところでコンパイルしたところ、警告がいくつか出ました。 その警告を無視して実行したところ、落ちました。 落ちた最大の原因は、変数BにNULLが入っているにもかかわらず 強引に"ABCD"をコピーしようとしたところにあると思います。 Bには、"ABCD"を格納できるだけの適切な領域が必要であるはずです。
お礼
なるほど。 やはり領域を確保しないとダメということですね。 ありがとうございます。
お礼
お礼が遅れてすみません。 わかりやすく解説していただきありがとうございます。