• ベストアンサー

C++ メモリの動的確保について

C++のメモリの動的確保について、以下のことが分からないので、教えて頂けないでしょうか? 適切にメモリ確保が行えていたとしても,あることに注意しないと実行時にプログラムが不正に停止することがある.「あること」について,また「あること」が起こるプログラムの例を示せ. いろいろ探したり試したりしたのですが、うまく説明できる内容が思い浮かびませんでした。 どうかよろしくお願い致します。

noname#225287
noname#225287

質問者が選んだベストアンサー

  • ベストアンサー
回答No.6

実行時エラーを出すのなら、手元のVisualC++ 2010 Express、Windows7の環境なら、 #include <stdio.h> #include <stdlib.h> int _tmain(int argc, _TCHAR* argv[]) {  char *mem;  mem = (char*)malloc(10);  mem[0x00000001] = 1; // ここは有効な領域内なので当然OK  mem[0x00000010] = 1; // ここは有効な領域外だがセーフ  mem[0x00000100] = 1; // ここも有効な領域外だがセーフ  mem[0x00001000] = 1; // ここで実行時にアクセス違反の例外が発生してプログラムが停止する  mem[0x00010000] = 1;  mem[0x00100000] = 1;  mem[0x01000000] = 1;  mem[0x10000000] = 1;  return 0; } とか。 > 実行すらできずに落ちる(停止)するにはどうすればいいのか いよいよ意味不明です。 コンパイル、リンク出来て、作成された実効形式(Winなら.exe)は、例外なく(1ステップでもって意味で)実行可能だと思いますが。 テキトーなテキストファイルの拡張子を.exeに変更したファイルなんかは、最近のWindowsでは実行できないようにチェックされてはじかれます。が、これはプログラムの問題で実行できないのと別の話。 Unixでファイルに実行権限が無くて実行できないのも、プログラムがどうこうで実行できないわけではないですし。 そもそも、「落ちる(停止)する」ってのは、何かしら実行された結果では。

noname#225287
質問者

お礼

私の説明が下手なばかりに迷惑をかけてしまい申し訳ございません。 大学の試験の過去問に出ていたのですが、私自身、言ってることが理解できず、求められている解答の見当がつきませんでした。 ただ、解答は複数考えられる、とは表記されていました。 みなさんの解答を参考に考えてみたいと思います

その他の回答 (5)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.5

なんとなくですけど、メモリを開放せずに確保し続けると、メモリが足りなくなるとか、一度開放したメモリを2度開放してはいけないとかそういう答を期待した設問なのかも。 いずれにしてもよくわからない設問ですね。どこに書いてあったんですか?

  • yymddttmm
  • ベストアンサー率34% (31/91)
回答No.4

設問?自体が曖昧、意味不明だから説明のしようがない。 たとえばアクセス違反で停止しても処理系の仕様による正常処理だから不正ではないとも言える。 どうなったら停止するかはOS、H/Wと処理系の問題であってC++の言語仕様とは関係ない。 再帰性呼び出しでスタックオーバーフローもあり得る。 HWによっては冷却ファンを強制停止して熱暴走も有りかな。

  • weavaest
  • ベストアンサー率15% (157/1020)
回答No.3

確保したメモリに対しての「あること」なのですか。つまり他の回答者が仰るような確保した領域外へのアクセスは、「あること」に該当しないのでしょうか。また、静的に確保したメモリでは起きず、動的に確保したメモリでしか起きないことなのでしょうか。 何だか漠然とした質問のために、回答し辛い気がします。

noname#225287
質問者

補足

例えば、int型で固定長配列p[10]を動的に確保したとして、p[-10]とかp[100]とかは普通にアクセスして使用できてしまうのですが、おそらく実行すらできずに落ちる(停止)するにはどうすればいいのかを聞いているのではないかと思います。

  • maiko0333
  • ベストアンサー率19% (840/4403)
回答No.2

確保したメモリー外のところをアクセスした。 例えば10バイトしか確保していないのに10文字を入力した。 インデックスがマイナスになってしまった。など

回答No.1

例えば、確保したメモリの外側にアクセスするとか。 > また「あること」が起こるプログラムの例を示せ. 例えば、 char型で10バイトのメモリを確保。 sprintf関数で、"Hello World!!"の13バイトの文字列を書き込み。 とか。 プログラムを不正に停止させる例でなくて、アクセス違反する例でいいんですよね? 停止するかどうか?は、処理系なんかによりますし。

関連するQ&A

  • C言語 動的なメモリの確保 実行できない

    malloc関数を使いメモリを確保しそこへ"ABCD"と記憶させ、ポインタ*Cを使い確保したメモリの内容を表示するプログラムです。 ********************************************* #include <stdio.h> #include <stdlib.h> int main(void) {   int i;   char *C;   C = (char *) malloc (sizeof(char) * 5);   C = "ABCD";   for(i = 0; i < 5; i++){     if(C[i] != NULL){       printf("%s", C[i]);    ←※エラー※     }   }   free(C);   return 0; } ********************************************* 正常にコンパイルできますが実行エラーになります。VCを使いF10のデバッグテストで※のところエラーになります。なぜなのでしょうか?

  • CGIがKILLされたら、Cで動的に確保したメモリは?

    C言語でCGIを製作していています。(環境:Linux + APACHE + gcc) malloc()などで動的に確保したメモリ内容を標準出力に表示している時に 出力先(閲覧者ですね)側から受信停止されたら、その後の処理はどうな るのでしょうか? その時の例外処理は、コンソールでのターミネイト処理と同じでいいので しょうか。 試しにAPACHEのログを見てみますと、出力は最後まで行われていないよ うです。本来そのCGIは120Kbyteの転送量が書き出されますが、受信停止 と思われる30kbyte程度で収まっています。 OS側でうまくやってくれれば、それにこしたことが無いのですが。 どうぞよろしくお願い致します。

    • ベストアンサー
    • CGI
  • 動的確保できるメモリ容量

    こんにちは. 2個のファイルを同時に開いて処理するプログラムを作成したところ, メモリの確保に失敗するエラー(std::bad_alloc)が発生してしまいます. *********************** 環境 OS:WindowsXP-sp2 メモリ:768 MB HD空き:約30GB 開発環境:C++Builder 6 *********************** 開こうとするファイルは,各250MB程度で,それぞれを読み込んだ後,それ ぞれに対して同じ大きさの配列を確保するため,必要メモリ容量は, 約 1GB 程度になります. ちなみに,配列の確保はnewを用いています. PCに搭載している物理メモリが768MBなので,仮想メモリにアクセスする のは当然だと思います.ただ,ハードディスクの空きも十分なので,実行 速度が遅くなったとしても,無事処理できると思っていました. ヒープサイズが関係していると思い,C++Builderのリンカの設定で予約ヒー プサイズを最大に設定しましたがダメでした. また,Windowsのシステムのプロパティで,仮想メモリを4000MBにしました がこれもダメでした. プログラムで一度に確保できるメモリサイズには限界があり,それ以上の サイズを確保することは不可能なのでしょうか? なお,2つのファイルを同時に開いて処理しようとするとエラーになって しまいますが,作成したソフトを2つ実行して,それぞれで上記ファイルを 1つずつ開くと,合計の必要メモリは同じにもかかわらず,エラーになりま せん. このときタスクマネージャでPF使用量を確認すると,1.2GBになっていました. 分かりづらい文章で大変申し訳ありませんでした. 何かアドバイスいただければありがたいです.

  • メモリの確保

    C++で倒立振子のプログラムを書いている者です。 現在、思考回数を500でやらせるために、500の配列を用意してやっているのですが、この思考回数を500以上にすると、コンパイルは通るのですが、実行画面が出てすぐ消えてしまう現象が起こってします。おそらく、メモリが足りないのだと思い、mallocを試してみたのですが同じ現象が起きてしまいましい、どうようにして解決していいのかわかりません。宜しくお願い致します。

  • メモリ確保方法を教えてください。

    Visual Studio.NET でC言語でプログラムを組んでいるのですが、二次元配列をたくさん使用したプログラムで、コンパイルして実行しようとするとエラーが表示されてしまいます。配列の要素を少なくすると実行はされるのですが、要素数が多くなるとエラーが表示されます。 実行時にユーザの使用メモリ数が制限されているなら、その使用メモリを増やす方法があれば教えていただけませんか?よろしくお願いします。

  • C++ 最適なメモリ確保

    画像処理をするために実験的にC++でプログラムを書いています。 malloc関数でBMP画像の画素位置を、画像画素分確保するだけのint型配列を作成するにはどうしたらよいでしょうか。 因みに、入力画像の解像度は640x480です。 一番左下の画素を(x,y)=(0,0)として考えています。 ある条件の画素に該当する画素座標を、下のStackX,StackYにx,y成分ごとに格納していくものです。 //////// int *StackX = (int *)malloc(sizeof(int)*100000); int *StackY = (int *)malloc(sizeof(int)*100000); //////// 上のように書くと、途中でクラッシュしてしまいます。 ですが、大目にメモリをとって //////// int *StackX = (int *)malloc(sizeof(int)*10000000); int *StackY = (int *)malloc(sizeof(int)*10000000); //////// で実行すると、最後まで動いてくれます。

  • 動的メモリ確保の外部関数

    画像処理関係のプログラムを作成しているのですが(C言語で)、動的にメモリ確保をすることが頻繁にあります。 そこで、どんな型(int,char,double,etc..)の場合でもメモリ確保できるような、1つの外部関数を作成したいと考えています。 例えば、 int Memory(引数) { 型宣言; int型の動的メモリ確保; char型の動的メモリ確保; double型の動的メモリ確保; return 0; } イメージでは、上のような感じです。 もしかして、このような考えは、不可能でしょうか? どなたか良いアドバイスがあれば、ご教授ください。 よろしくお願いします。

  • メモリ確保の謎。

    C言語のメモリの確保の所でふと疑問に思ったのですが、 malloc,calloc,realloc,memset,memcpyなどの関数を使うときって #include <stdio.h> #include <stdlib.h> #include <memory.h> #include <malloc.h> とか書かないといけないと本にはありますが、#include <stdio.h>だけで なんのエラーにもならずに実行できてしまうのはなぜでしょうか? 実際のプログラムにはmallocとreallocしか使ってないのですが、#include <stdio.h>でできてしまいます。 でも教科書には他にも書かなきゃいけないとかいてありますが、なぜ書かなくても実行できてしまうのでしょうか?

  • 配列の操作やメモリの確保のミスについて

    プログラミング初心者です。 Visal Studio 2010を使用してC++の勉強をしています。 配列の操作やメモリの確保でエラーを起こした場合、OSや他のプログラムにもエラーを引き起こすことがあるのでしょうか? (記述・実行しているプログラムは教材に記されているただのコンソールアプリです。複雑であったり大規模なものではありません。) たとえば、mallocで配列のメモリを確保したが、その配列の要素数以上に値を書き込んだり参照したり、freeをし忘れたりした場合です。 その時、想定していないメモリ領域に値が書き込まれることで、他のプログラムが壊れたりするんじゃないかと心配です。 というのも、配列の操作やmallocを失敗したときに、パソコンの動作が不安定になるのです。(画面がちらついたり、表示がおかしくなる。) explorer.exeを再起動するだけで収まるように見えるのですが、何が起きているのか不思議です。 以上になります。長文お読みいただきありがとうございました。 よろしくお願いいたします。

  • 動的なメモリ領域の確保

    double型変数5個分のメモリをmalloc関数により確保し,その確保した要素のアドレスを表示するように,プログラムを作る問題で、 (注)に「 %pで表示するためには,double型へのポインタ(double *)をvoid型へのポインタ(void *)にキャストする必要がある.」と書かれていたのですが、どういうことでしょうか? 以下のようでいいのでしょうか? #include<stdio.h> #include<stdlib.h> #define COUNT 5           // 動的に確保するメモリ領域数を示すマクロ定数の定義 int main(void) {  // 動的に確保するメモリ領域のアドレスを保持するポインタ変数の宣言  double * pointer;  int i;                  // for文で使用する変数の宣言  // int型変数5個分のメモリ領域を確保  pointer = (double *)malloc(sizeof(double) * COUNT);  if(pointer == NULL) {        // メモリ領域の確保が失敗した場合   printf("メモリ領域を確保できませんでした.\n");   exit(1);                // プログラムの終了  }  for(i = 0; i < COUNT; i++)   printf("%d番目のアドレスは%pです.\n", i + 1, pointer + i);  free(pointer);            // 確保したメモリ領域の解放  return 0; }

専門家に質問してみよう