C++のメモリアクセスエラーの解決方法

このQ&Aのポイント
  • C++でint型の配列を0で初期化する方法について質問します。
  • コンストラクタ内でpush_counter[20] = {}と書いたところ、エラーが発生しました。
  • エラーメッセージは「CRT detected that the application wrote to memory after end of heap buffer;」です。解決方法を教えてください。
回答を見る
  • ベストアンサー

C++のメモリアクセス?のエラー

int型の配列を0で初期化しようと思い ~クラスメンバ~ int push_counter[20] ; ~コンストラクタ内~ push_counter[20] = {}; と書いて実行、終了したら CRT detected that the application wrote to memory after end of heap buffer; というエラーが出ました。 存在しないものにアクセスしてますよー って意味だと思うのですが、 for( int i=0 ; i<20 ; i++ ) push_counter[i] = 0; にすればエラーは出なくなったのですが、 push_counter[20] = {}; この書き方でも出来ると思うのですが何故なのでしょうか…

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

  • ベストアンサー
  • Tasuke22
  • ベストアンサー率33% (1799/5383)
回答No.1

int push_counter[20] ; この配列の要素数は20ですね。 要素番号は0~19です。 push_counter[20]は21番目の要素を参照しようとしています。 PCでのカウンターは0から始まることがことが多いです。

majuppitto
質問者

お礼

なるほど! あるサイト様で int data[100] = {}; と書いておられたので、 そのまま書いてしまいましたが 初期化と代入の違いだったってことですね(恐らく…) ありがとうございました!

関連するQ&A

  • HEAP に関すること

    HEAP CORRUTOPN DETECTED: AFTER Normal block(c# 179) at 0x003EA6D0 CRT detected that the application wrote to memory after end of heap buffer; というエラーがでたのですが、最後の二行を訳すと、 ヒープ領域が終わったあとにアプリケーションがメモリーに書き込んだ のをCRTが発見したということになると思うのですけど、 これは、ヒープを使い切ったということになるのでしょうか? それとも、本来上書きしてはならないヒープの部分に上書きしたことに なるのでしょうか? ネットで今調べているのですがなかなか結論が出せなくて。

  • C言語、配列とポインタとアスタリスクの関係

    ちょっと行き詰まっています。 苦しんで覚えるCで勉強しているのですが、まさに苦しんでいます。 http://9cguide.appspot.com/19-01.html #include <stdio.h> #include <stdlib.h> int main() { int i; int *heap; heap = (int *)malloc(sizeof(int) * 10); if (heap == NULL) exit(0); for (i = 0;i < 10;i++) { heap[i] = i; } printf("%d\n",heap[5]); free(heap); return 0; } int *heap; ここで int ポインタを宣言しています。 heap = (int *)malloc(sizeof(int) * 10); ここでヒープを確保しています。(int *) のキャストも sizeof(int) も理解できました。 for (i = 0;i < 10;i++) { heap[i] = i; } まず1点目の疑問はここです。 変数 heap は「ポインタ変数」です。それでいて配列です。 ポインタ変数は、プログラムの文中で通常の変数として使うときには「*heap」のように先頭にアスタリスクを付けなければならかなったと記憶しています。 アスタリスクなしの「heap」はアドレス格納用の変数ではないでしょうか。 printf("%d\n",heap[5]); そして、その疑問をよそに、この命令が成り立っているようです。 画面上に出される結果は「5」であり、変数「heap」がただの配列として機能しているように見えます。 この printf 次のように書き換えると、エラーが出てコンパイルできませんでした。 書き換え実験1 printf("%p\n",*heap[5]); アスタリスクを付けて、通常の変数として扱い、受ける方も「%d」から「%p」に書き換えてアドレスを表示してみようと思ったのですが、 「「pointer」を付け忘れています。」というエラーが表示されました。 書き換え実験2 printf("%p\n",heap[5]); 受ける方を「%d」からポインタを受ける「%p」にしましたが、変数の方はアスタリスクなしです。 すると、結果はアドレス「00000005」が返ってきました。 (変数にアスタがないのになぜ?) 書き換え実験3 printf("%d\n",*heap[5]); これはもうめちゃくちゃですが、一応やってみました。コンパイルエラーで、 「「pointer」を付け忘れています。」というエラーが表示されました。 つまり、こういうことです。 0:printf("%d\n",heap[5]); //5 1:printf("%p\n",*heap[5]); //エラー 2:printf("%p\n",heap[5]); //00000005 3:printf("%d\n",*heap[5]);//エラー この結果から推測するに、アスタリスクはそもそも付けるとエラーになり、アドレスを表すか、そのアドレスに格納された値を表すかを切り替えるには、単にその変数を受ける「%d」や「%p」を変えるだけ、ということになるのだと思います。 mallocで返ってくるのは、ポインタ変数(の配列)だと思うので、変数のモードを切り替えるためにアスタリスクが必要なのだと思っていましたが、どこかで重大な勘違いをしているようです。 この件について、どなたか教えていただけないでしょうか。

  • C++/Cこういうことは可能でしょうか?違う型の引数をとって同じようなことをする

    お世話になります。 C++の初心者です。 違う引数をとって同じ関数にいれて同じようなことをさせるというのは できるのでしょうか? コンストラクタの作成方法で可能?? 共用体で可能?? 例: 型の違う構造体A,Bがある。 構造体のメンバには同じstatusが存在する。 statusが1のときだけresultを+し値を返す。 typedef struct{   int status;   int b; } DATA_A; typedef struct{   int status;   int b;   int c; } DATA_B; int test(DATA_AかDATA_Bを引数でとる,int data_num){ //data_numはデータ数  int i=0;  int counter=0;  for(i=0;i<data_num;i++){   //DATA_AまたはDATA_Bのメンバstatusが1ならcounterを+する   if(DATA_A.status == 1){    counter++;   }  }  return counter; } 以上のような感じです。 引数の型が違う2つの関数を作ればできますが、 同じことをさせるので同じ関数で実現できないかなと思って 質問させてもらいました。 よろしくおねがいします。

  • GlobalAlloc生成メモリの開放でエラー

    とある大学生です. 研究でCのプログラムを書いており,メモリの生成と解放をしているのですが,どうしてもエラーが起きてしまい,困っております. そこで,この場をお借りして,みなさまにお力添えをしていただければと思い,質問しました. 問題のプログラムは以下のようになっております. ------------------------------------------------- #define BUFFER true FILE *fp = NULL; unsigned short int *lpBuffer = NULL; HGLOBAL hGlobal = NULL; char FilePath[] = "data.txt"; int DataDepth = 240; #if BUFFER unsigned short int buffer; #endif // 外部ファイル読み込みモード(r)で開く fopen_s( &fp, FilePath, "r" ); // ファイル読み込みモードで開く // データ領域の割り当て hGlobal = GlobalAlloc( GPTR, DataDepth*sizeof(unsigned short int) ); lpBuffer = (unsigned short int*)hGlobal; // 外部ファイルからデータ読み込み for( int i=0; i<DataDepth; i++ ){ #if BUFFER if( fscanf_s( fp, "%x", &buffer )!=EOF ) // 16進数で読み込む lpBuffer[i] = buffer; #else fscanf_s( fp, "%X", &lpBuffer[i] ); // BUFFER = true #endif // メモリ領域の開放 GlobalFree( hGlobal ); // BUFFER = falseのときエラー発生個所 // ファイルクローズ fclose( fp ); ------------------------------------------------- データファイル(data.txt)は以下のような構成になっており,240行あります. ------------------------------------------------- 0000 0001 0002 0003 .... 00EF ------------------------------------------------- このプログラムでBUFFER = trueのときは以下のようなエラーが本コード(関数)を終えた箇所で発生します.デバッグ実行で無視できます. +++++++++++++++++++++++++++++++++++++++++++++++++ Run-Time Check Failure #2 - Stack around the variable 'buffer' was corrupted. +++++++++++++++++++++++++++++++++++++++++++++++++ このプログラムでBUFFER = falseのときは以下のようなエラーが発生します.デバッグ実行で無視できないものです. +++++++++++++++++++++++++++++++++++++++++++++++++ Windows によって WinUSB_Control.exe でブレークポイントが発生しました。 ヒープが壊れていることが原因として考えられます。WinUSB_Control.exe または読み込まれた DLL にバグがあります。 あるいは、WinUSB_Control.exe がフォーカスを持っているときに、ユーザーが F12 キーを押したことが原因として考えられます。 +++++++++++++++++++++++++++++++++++++++++++++++++ ネットで調べて原因を調べたのですが,わからなく今に至ってます. 開発環境はWindows 7 64bitでMicrosoft Visual Studio 2010です. 原因や解決方法をご存知の方は,お力添えいただけたら幸いです. ご回答,よろしくお願い致します.

  • make_heap()が分かりません

    #include <iostream> #include <vector> #include <algotithm> using namespace std; int main() { vector<char> v; int i; for(i=0;i<20;i+=2)v.push_back('A'+i); couti<<"sequence before building heap:\n"; for(i=0;i<v.size();i++)cout<<v[i]<<" "; cout<<"\n\n"; make_heap(v.begin(),v.end()); //? couti<<"sequence after building heap:\n"; for(i=0;i<v.size();i++)cout<<v[i]<<" "; cout<<"\n\n"; } の結果が sequence before building heap: A C E G I K M O Q S sequence after building heap: S Q M O I K E A G C ということですが make_heap() の機能がわかりません make_heap() の機能・動作に付いて教えてください (書き間違いがあるかもしれませんので容赦ください)

  • C言語で変更していただきたい所があるのですが・・・

    下のソースを加減乗除だけでなく、余りを求める演算(%)やべき乗演算(^)も使えるようにしたいのですがうまくいきません。 どなたか変更例をお見せできますでしょうか? #include <stdio.h> #include <stdlib.h> #define STACK_MAX 10 /* 配列によるスタック構造 */ double stack[STACK_MAX]; /* スタック頂上の位置(最下部からのオフセット)*/ int stack_top = 0; /* スタックへのpush */ void stack_push(double val) { if(stack_top == STACK_MAX) { /* スタックが満杯になっている */ printf("エラー:スタックが満杯です(Stack overflow)\n"); exit(EXIT_FAILURE); } else { /* 渡された値をスタックに積む */ stack[stack_top] = val; stack_top++; } } /* スタックからpop */ double stack_pop(void) { if(stack_top == 0) { /* スタックには何もない */ printf("エラー:スタックが空なのにpopが呼ばれました" "(Stack underflow)\n"); exit(EXIT_FAILURE); return 0; } else { /* いちばん上の値を返す */ stack_top--; return stack[stack_top]; } } int main(void) { char buffer[256]; double cal1, cal2; int i; do { printf("現在のスタック(%d個):", stack_top); for(i = 0; i < stack_top; i++) { printf("%0.3f ", stack[i]); } printf("\n>"); fgets(buffer, 255, stdin); switch(buffer[0]) { case '+': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 + cal1); break; case '-': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 - cal1); break; case '*': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 * cal1); break; case '/': cal1 = stack_pop(); cal2 = stack_pop(); stack_push(cal2 / cal1); break; case '=': /* =の場合はこのすぐあとでwhile文からも抜ける */ break; default: /* 入力された値は数字のはずなので,スタックに積む */ stack_push(atoi(buffer)); break; } } while(buffer[0] != '='); printf("計算結果は%f です。\n",stack_pop()); if(stack_top != 0) { printf("エラー:スタックにまだ数が残っています\n"); return EXIT_FAILURE; } return EXIT_SUCCESS; }

  • C言語 動的なメモリの確保 コンパイル時エラーも警告もないのに実行できない

    配列A[3]を{2, 4, 6}と初期化させ、malloc関数を使いメモリを確保しそこへ先程の配列Aの要素を記憶させ、ポインタ*Nを使い確保したメモリの要素を表示するプログラムです。 ********************************************* #include <stdio.h> #include <stdlib.h> int main(void) {   int A[3] = {2, 4, 6};   int i;   int *N;   N = (int *) malloc (3);   for(i = 0; i < 3; i++){     N[i]= A[i];   }   for(i = 0; i < 3; i++){     printf("%d", N[i]);   }   free(N);   return 0; } ********************************************* VCを使いF10のデバッグテストでは正常に動くのですが、コマンドラインからではエラー報告画面がでます。なぜなのでしょうか?

  • 非常にはずかしい質問ですが 配列の質問です。

    C言語の勉強で時間が経つごとに、肝心の基礎が忘れがちになるのですよね。 それに、配列に対しての説明ってほとんど文字列ばかりで整数はみつからないです。 今回の質問は ・int型配列の要素ひとつずつ代入するにはどうするか? ・同じ数字を代入させないにはどうするか? ・配列中n個の要素を表示させるにはどうするのか? 条件 1、配列の要素はn個 2、同じ数は× 一応かいてみました。 { int buffer[6], i, j, signal ; srand((unsigned int)time(NULL)); for( i = 0 ; i < 6 ; i++){ buffer[i] = rand()%42+1; for( signal = 0 , j = 0 ; j < i ; j++ ){ if(buffer[i] == buffer[j]){signal = 1; break;} } if(signal == 0){break;} } printf("%d\n",buffer);

  • C++ 動的確保について

    学校の演習課題で「クラス Array のメンバ変数を以下のように変更して,配列のサイズを実行時に決められるようにしたい.コンストラクタを適切に修正しなさい.配列のサイズはコンストラクタの引数で指定できるようにすること.main 関数内のオブジェクトの宣言部分を適当に変更して動作を確認しなさい.」という課題が出ました。 指示のメンバ変数の変更は、sizeを定数にしていたものを変数にし、arrayを配列からポインタにする点です。 もとのプログラムはI、私がいじったものがIIです。どうにもセグメンテーションフォルトから抜け出せなくて困っています。どのようにしたら題意のプログラムになるのでしょうか? よろしくお願いします。 ここからI~ #include <iostream> using namespace std; class Array{ private: const static int size = 6; int array[size]; public: Array( ); int getSize( ); void put( int index, int data ); int get( int index ); void show( ); }; Array::Array( ) { for ( int i = 0; i < size; i++ ) { array[i] = 0; } } int Array::getSize( ) { return size; } void Array::put( int index, int data ) { array[index] = data; } int Array::get( int index ) { return array[index]; } void Array::show( ) { cout << "| "; for ( int i = 0; i < getSize( ); i++ ) { cout << get(i) << " | "; } cout << endl; } int main( ) { Array array1; array1.put(1, 2); array1.put(4, 1); array1.show( ); return 0; } ~ここまでI ここからII~ #include <iostream> using namespace std; class Array{ private: int size; int *array; public: Array(int s); ~Array(); int getSize(); void put(int index, int data); int get(int index); void show(); }; Array::Array(int s) { size = s; array = new int; for (int i = 0; i < size; i++) { *array = 0; array++; } array -= size; } Array::~Array() { delete[] array; cout << "デストラクタが呼ばれました。配列の要素数分のメモリを開放します." << endl; } int Array::getSize() { return size; } void Array::put(int index, int data) { *(array + index) = data; } int Array::get(int index) { return *(array + index); } void Array::show() { cout << endl << "| "; for (int i = 0; i < getSize(); i++) { cout << get(i) << " | "; } cout << endl; } int main() { int s = 0; cout << "確保するサイズを入力してください:"; cin >> s; Array array1(s); array1.put(1, 2); array1.put(4, 1); array1.show(); return 0; } ~ここまでII

  • objective-C(Xcode)に関して質問があります。

    objective-C(Xcode)に関して質問があります。 新規プロジェクトからview-base Applicationテンプレートを使用してプロジェクト(TestClass.xcodeproj)を作成します。 そうすると、TestClassAppDelegate.m, TestClassAppDelegate.h, TestClassViewController.h, TestClassViewController.mが Classesフォルダーに作成されます。このプロジェクトに自分で作成するクラス(MyTestClass)を追加するにはどうすれば良いのでしょうか? 下記のコードではエラーはでませんが、tc.counterにint 10が代入さず、0(nil)が出力されます。 (interfacebuilder でボタンのみ設置、ボタンを押すとpushが呼ばれ、logを残す) ===MyTestClass.h===== #import <Foundation/Foundation.h> @interface TestClass : NSObject { int counter; } @property int counter; @end ===MyTestClass.m===== #import "TestClass.h" @implementation TestClass @synthesize counter; -(int)calcPlus{ return counter = counter+10; } @end ===TestClassViewController.h==== #import <UIKit/UIKit.h> #import "TestClass.h" @interface TestClassViewController : UIViewController { TestClass *tc; } -(IBAction) push; -(void)calc; @end ===TestClassViewController.m=== #import "TestClassViewController.h" #import "TestClass.h" @implementation TestClassViewController -(IBAction)push{ tc.counter = 10; NSLog(@"%d", tc.counter); } サンプルコード(iPhoneUnitTests ((calc)))をみても、特別なことはなく、ヘッダーの読み込みさえ出来てれば クラスが使えそうなのですが・・・。 コメントをいただければ、幸いです。

専門家に質問してみよう