• 締切済み

2つのコードの違いについて

以下は間違ったコードですが、コード1では”不正な処理~”が出ますがコード2では出ません。 同じコードに思えるのですが、どうして違いが出るのですか? <コード1> void func(void) {  void *buf1[10];  static int i;  for (i = 0; i < 100; i++) {   buf1[i]=0 ;  } } int main(void) {  int buf[1000];  func();  return 0; } <コード2> int main(void) {  int buf[1000];  void *buf1[10];  static int i;  for (i = 0; i < 100; i++) {   buf1[i]=0 ;  }  return 0; }

  • mk1234
  • お礼率94% (1832/1940)

みんなの回答

回答No.2

推測のですが、コード2でも、 int buf[1000]; の宣言を取ると不正な処理とかいうエラーになるんじゃないでしょうか。 コード1だと、func() が使用しているスタック領域(スタック領域っておわかりになります?)は void *buf1[10]; の分しかないので、i > 9 でスタック領域以外のメモリにアクセスしてしまってエラーになるのではないでしょうか。 コード2だと、 void *buf1[10]; の後ろ ( i > 9 が指すところ ) に、使用されていない buf[1000] の分のスタック領域があって、スタック領域外にアクセスせずにすんでいるだけではないでしょうか。 ( C/C++ の規約としては、宣言の順序と逆の順序でメモリ上に配置される、ということが約束されているのかどうかは、私は知りません。コンパイラによって異なるのかも・・・) Microsoft のコンパイラだと、オプションの指定で、こういうエラーをチェックするコードを埋め込むようなことができたような気がします。

mk1234
質問者

お礼

回答ありがとうございます。 回答頂いたことをヒントに考えて漸く分かりました。 コード1は関数の復帰情報等が破壊されるからですね。

  • yusuke_
  • ベストアンサー率53% (8/15)
回答No.1

コード1では  for (i = 0; i < 100; i++) {   buf1[i]=0 ;  } と100回繰り返すに対して、  void *buf1[10]; と10までしか宣言してません。 mainの中では1000まで宣言していますが、 これはローカルなので関数funcには渡されないように思われます。 ですのでエラーが出るのではないでしょうか? まあ、私はプログラミングはまだまだ端くれなんで自信がありませんが(^^;

mk1234
質問者

お礼

回答ありがとうございます。 変数名を明確に変えれば良かったのですが、コード2はの記述はint buf[1000]; であってint buf1[1000];ではないのですが。

関連するQ&A

  • プログラムがわかりません

    C言語の本を読んでいるんですが、詰まってしまいました。プログラム自体は単純なのですが #include<stdio.h> void hello(void) { fprintf(stderr,"hello!\n"); } void func(void) { void *buf[10]; static int i; for(i=0;i<10;i++) { buf[i] = hello; } } int main(void) { int buf[100]; func(); return 0; } のスタックオーバーフローのプログラムです。 1. 要素100のint型配列を宣言 2. 関数funcの呼び出し 3. void *buf[10]; まずここでがわかりません。なぜポインタが   でてきたのか?またbufの要素数は100では? 4. buf[i] = hello; のループ    これもわかりません。配列に関数を代入しているのでしょうか?     5.  fprintf(stderr,"hello!\n"); これもまたわかりません。    fprintfの最初の引数は出力先ですが、なぜ標準エラー出力なの   でしょうか? 時間のあるかた解説お願いします。

  • Cygwinでg++がグローバル関数をはじいてしまう

    現在Win XP上にGygwinを導入し C++の勉強をしています。 書籍を購入し、以下のプログラムを試したところ グローバル関数宣言をしているにもかかわらず main() とfunc1()中で変数”count”が undeclared (first use this function) として弾かれてしまいます。 どうしてなのでしょうか? よろしくお願いします。 //example global variavle. #include<iostream> using namespace std; void func1(); void func2(); static int count; //This is global variavle. int main() { int i; //This is local variavle. for(i=0; i<10 ; i++){ count = i * 2; func1(); //calling func1(). } return 0; } void func1() { cout << "count: " << count; //access global "count" cout << "\n"; func2(); //calling func2(). } void func2() { int count; //define local "count" for(count=0;count<3;count++) { cout << "."; } }

  • ソースコードの流れについて

    下記ソースコードの流れを詳しく解説していただけませんか。表示結果が理解できません。 class Th extends Thread{ public void run(){ for(int i = 0; i < 2; i++)System.out.print(" "+ Main4_1_49.count + i); } } public class Main4_1_49{ static int count = 0; public static void main(String[] args){ Th[] tr = new Th[6]; for(int i = 0; i < 5; i++){ count++; tr[i] = new Th(); tr[i].setPriority(i * 2 + 1 ); tr[i].start(); } } }

  • クラス内の関数内static変数について

    クラス内の「staticではないメンバ関数内で定義される」static変数の初期化タイミングはいつでしょうか? 自分としてはクラスのインスタンス生成時に初期化されるものだと思っていたのですが、どうもそうでは無さそうだという現象に出会ったもので。 例えば以下のようなサンプルプログラムがあるとします。 --------------------------------------- class TA { public: void func(int i); }; void TA::func(int i) { static int d=0; d += i; std::cout << d << std::endl; } int main() { for(int i=1; i < 3;i++) { TA ta; ta.func(i); ta.func(i); ta.func(i); } } --------------------------------------- これを実行した時、自分としては 1 2 3 2 4 6 という結果を期待していた訳ですが、実際には 1 2 3 5 7 9 という結果になりました。 ということは、もしかしてメンバ変数ではなくともクラス内に現れるstatic変数はstaticなメンバ変数と同等ということなのでしょうか? 実際、上記ソースのforループ内にもう一つclass TAのインスタンスtbを追加してみると、 --------------------------------------- for(int i=1; i < 3;i++) { TA ta; ta.func(i); ta.func(i); ta.func(i); TA tb; tb.func(i); tb.func(i); tb.func(i); } --------------------------------------- 1 2 3 4 5 6 8 10 12 14 16 18 となりました。 (まぁstaticではないメンバ変数に置き換えれば一応解決するのですが、個人的に何か凄く気持ち悪く感じて・・・)

  • (void *)と&の違い

    #include<stdio.h> void * func(void *p){ printf("□■□func開始□■□\n"); printf("pのアドレス = %p\n",p); printf("p = %d\n",(int)p); (int)p += 100; printf("p = %d\n",(int)p); printf("□■□func開始□■□\n"); return NULL; } int main(void){ int number = 30; printf("numberのアドレス = %p\n",&number); func((void *)number);★1 return 0; } -------------------------------------------------------------- #include<stdio.h> void * func(int *p){ printf("□■□func開始□■□\n"); printf("pのアドレス = %p\n",p); printf("p = %d\n",*p); *p += 100; printf("p = %d\n",*p); printf("□■□func開始□■□\n"); return NULL; } int main(void){ int number = 30; printf("numberのアドレス = %p\n",&number); func(&number);★2 return 0; } 上記の2つは同じ結果になるのですが★1と★2のそれぞれの違いがわかりません。どなたかご教授をお願いします。

  • 2つの疑問

    1 main関数の最後のreturnは何に用いられているのでしょうか?別にreturn 0;で0以外の値を代入してもプログラムは何の問題もなく動きます。 2 以下のプログラムなのですが、 int main() { void *str[10]; int i; for(i=0;i<10;i++) { str[i] = func; } return 0; } 自分では配列strに関数funcの先頭のアドレスが来ていると解釈しています。ここで、配列strは4バイトづつ並んでますが、関数の領域の大きさが4バイトをこえるとエラーがおきるのではないかと思い、いろいろ関数をいれてみましたが、エラーは起きませんでした。なぜせしょうか?

  • C/C++関数間でのStringクラスの扱い

    以下のようなコードを実行してみましたが思い通りに動いてくれません. "sample"という文字列がstrへとコピーされると思ったのですが. stringクラスのc_str()メソッドはconst char*だと言っているので無理矢理キャストしたのが原因でしょうか.stringクラスは記憶領域を自動で変更してくれるのではないのですか.それともこの挙動は仕様ですか. -------- 以下コード -------- #include <iostream> #include <string> using namespace std; int func(char *); int main(void) {     string str("");     func((char *)str.c_str());     cout << "String: " << str << endl;     return EXIT_SUCCESS; } int func(char *buf) {     buf = "sample";     return 0; } -------- 以上コード --------

  • staticで初期化した変数(?)を使って初期化

    次の3つのプログラム、1番目はコンパイルエラーになりますが、下2つはエラーになりません。1番目のプログラムのエラーメッセージ:初期化子が定数ではありません。 処理系にかかわらずそうだとしたら、その理由はなんでしょうか。 ---------------------------------- int main(void) { static int a=5; static int b=a; return 0; } ---------------------------------- int main(void) { static int a=5; int b=a; return 0; } ---------------------------------- int main(void) { int a=5; int b=a; return 0; }

  • C++の(左辺値)参照を参照渡し

    おそらく基本的なところなのですが 参照を参照で渡すのはNG…? という記述をどっかで見たような見なかったような気がするのですが 再度確認しようと思うも見つからず。 気のせいかもしれません。 または そのときの文章では「参照」という言葉が別の意味で使われていたかもしれませんが 以下のように、左辺値参照を左辺値参照渡しするコードはconst参照、非const参照問わず規格上OKでしたっけ? #include <stdio.h> void func(int& n){ if ( n%7 ){ n+=9; func(n); } else return; } int main(void){ int i = 1; func(i); printf( "%d", i ); return 0; }

  • Javaについて教えてください。

    Javaのソースコードで以下のコードを実行すると表示されないのですがなぜでしょうか? public class Sample{ public static void main(String[] args){ for (int i = 0 ; i >= 5; i++){ System.out.println(i); } } }

専門家に質問してみよう