メモリの開放でエラーが発生する原因と解決方法

このQ&Aのポイント
  • Cのプログラムにてメモリの生成と解放を行っている際にエラーが発生しており、原因と解決方法を知りたい。
  • BUFFERがtrueの場合、特定の箇所でエラーが発生し、デバッグ実行で無視できるが、BUFFERがfalseの場合はエラーが発生し、無視できない。
  • 開発環境はWindows 7 64bitでMicrosoft Visual Studio 2010を使用している。
回答を見る
  • ベストアンサー

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です. 原因や解決方法をご存知の方は,お力添えいただけたら幸いです. ご回答,よろしくお願い致します.

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

  • ベストアンサー
  • Wr5
  • ベストアンサー率53% (2177/4070)
回答No.1

>if( fscanf_s( fp, "%x", &buffer )!=EOF ) >fscanf_s( fp, "%X", &lpBuffer[i] ); http://msdn.microsoft.com/ja-jp/library/6ttkkkhh%28v=vs.100%29.aspx で…xは「int へのポインター。」となっています。 実際に渡しているのはshort int型へのポインタになっていますよね? じゃあ、余った分はどこに書き出しましょうか?? 故に… >Run-Time Check Failure #2 - Stack around the variable 'buffer' was corrupted. unsigned short intの変数bufferの後ろの領域に放り込んでみたり、 >ヒープが壊れていることが原因として考えられます。WinUSB_Control.exe または読み込まれた DLL にバグがあります。 GlobalAlloc()で確保した領域の後ろをぶっ壊してみたりしているのではないですか?

apollograffitti
質問者

お礼

ご回答いただき,誠にありがとうございました. 原因はご指摘の通り,フォーマット指定子の箇所でして,これを修正して処理を実現することができました. おかげで,研究を前進することが出来そうです.

関連するQ&A

  • 画像を読み込んでヒストグラムを作るプログラム

    2値化画像を読み込んで、ヒストグラムを表示させるプログラムを作りたいのですが、 以下のソースを作成したのですが実行中にエラーが発生して困っています。 よろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #include <conio.h> #define width 640 #define height 480 int main(int argc, char* argv[]) { unsigned char image[640*480]; unsigned char header32[1078];//ビットマップ情報 int i; int *histogram; FILE *fp1; unsigned char buffer1[640*480]; for(i=0; i<640*480; i++) { image[i]=0; buffer1[i]=0; } fp1=fopen("koshimizu1.bmp","rb"); // fread(image,1,640*480,fp1); fread(header32,1,1078,fp1); fread(buffer1,width,height,fp1); fclose(fp1); for(i=0;i<256;i++){ histogram[i]=0; } for(i=0;i<640*480;i++){ histogram[image[i]]++; } for(i=0;i<256;i++){ printf("%d %d \n",i,histogram[i]); } return 0; }

  • ファイルポインタfpを、何バイト読んだかカウンタとして使うには?

    ファイルポインタfpを、何バイト読んだかカウンタとして使うには?どうしたら良いか教えてください。binary fileをオープンして、1Byteずつc=fgetc(fp); を繰り返し読込み特定の処理します。数百万バイトを読んだあたりで、こけるので、何バイト目あたりでこけているのか知りたいというのが動機です。 fp構造体の中で、今、ファイルの冒頭から何バイト読んだところ、という情報を引っ張り出して1Byte読み込むごとに(ずらずらとでいいので)表示したいです。fp->current_byte とかいう情報があるように想像するのですが、どうでしょうか。以下に、#include<stdio.h>の中で、FILE を引用します。 typedef struct { unsigned char *curp; /* Current active pointer */ unsigned char *buffer; /* Data transfer buffer */ int level; /* fill/empty level of buffer */ int bsize; /* Buffer size */ unsigned short istemp; /* Temporary file indicator */ unsigned short flags; /* File status flags */ wchar_t hold; /* Ungetc char if no buffer */ char fd; /* File descriptor */ unsigned char token; /* Used for validity checking */ } FILE; /* This is the FILE object */

  • プログラム(C)

    #include <stdio.h> #include <stdlib.h> #define FNAME "smp.bmp" #define WSIZE 256 #define HSIZE 256 #define BSIZE 1024 int main(void) { struct BMPFILEHEADER { ・   ・ }; struct BMPINFOHEADER { ・   ・ }; unsigned char img[HSIZE][WSIZE][3]; unsigned char buf[BSIZE]; struct BMPFILEHEADER lpHead; struct BMPINFOHEADER lpInfo; FILE *fp; int i; int j; int k; fp = fopen(FNAME,"rb"); if (fp==NULL) { printf("ファイルをオープンできません\n"); return 0; } fread(&lpHead.bfType, sizeof(unsigned short),1,fp); fread(&lpHead.bfSize, sizeof(unsigned int),1,fp); fread(&lpHead.bfReserved1, sizeof(unsigned short),1,fp); fread(&lpHead.bfReserved2, sizeof(unsigned short),1,fp); fread(&lpHead.bf0ffBits, sizeof(unsigned int),1,fp); fread(&lpInfo, sizeof(struct BMPINFOHEADER),1,fp); for(i=0;i<HSIZE;i++) { fread(buf,sizeof(unsigned char),WSIZE*3,fp); for(j=0;j<WSIZE;j++) { for(k=0;k<3;k++) { img[HSIZE-1-i][j][k]=buf[j*3+k]; } } } fclose; return 0; } このプログラムはBMP画像を読み込むプログラムなんですが このプログラムに画素値を出力するプログラムにしたいのですがうまくできません。 結果は(真っ白な画像の時)255255255・・・255255と出力したいのです。白黒画像なのでR=G=Bで1画素値は255だけでいいのですが。どうしても255255255や25500などとでてしまいます。 アドバイスお願いします。(800字までなので構造体の宣言は抜いてしましました) 。

  • C言語でファイル読み書きを早くしたい。

    いつも利用させてもらって助かっています。 あるプログラムを作成しているのですが、ファイル入力の部分がネックとなってしまって、全体が使いものにならない状況に陥っています。 たくさんのデータをfread1回で読み込むことにより、読み込み速度はずいぶんと改善されましたが、まだ圧倒的に遅い状況です。システムコールを使いましたが、ほとんど改善されませんでした。 読み込み/書き込みの速度を改善する方法として,SSDメモリを使ったりする方法があると思いますが,プログラムの観点から改善できるところはないでしょうか? 下に、ファイル読み込みの部分だけ記述したコードを添付させて頂いたので、改善できる点があれば、御指摘頂けると助かります。 なお、前提として, (1)データはスタック領域だと不足するので、ヒープ領域に確保 (2)データファイルは改行無しの一連のデータ とします。 ちなみに、環境は OS   : CentOS5.3 memory   : 6GB コンパイラ : gcc です。 よろしくお願いします。 //----------------------------------------------------- //通常バージョン #include <stdio.h> #include <stdlib.h> #define SIZE (512*1024*1024) //500MB int main(void) { unsigned long int i; unsigned char *data; FILE *fp; data = (unsigned char *)malloc(SIZE); if(data == NULL) { printf("メモリが確保できません\n"); exit(EXIT_FAILURE); } fp = fopen("filein.dat", "rb"); fread( data, sizeof( unsigned char), (int)SIZE, fp ); fclose(fp); /* //表示 for( i=0; i<SIZE; i++ ){ printf("%2x", data[i]); } puts(""); */ fp = fopen("fileout.dat", "w"); fwrite( data, sizeof( unsigned char), (int)SIZE, fp); fclose(fp); free(data); return 0; } //----------------------------------------------------- //readシステムコールを使ったバージョン #include <stdio.h> #include <stdlib.h> #define SIZE (512*1024*1024) //500MB int main(void) { unsigned long int i; unsigned char *data; data = (unsigned char *)malloc(SIZE); if(data == NULL) { printf("メモリが確保できません\n"); exit(EXIT_FAILURE); } int fd; fd = open( "filein.dat" ); read( fd, data, sizeof(unsigned char)*SIZE); close(fd); /* //表示 for( i=0; i<SIZE; i++ ){ printf("%2x", data[i]); } puts(""); */ FILE *fp; fp = fopen("fileout.dat", "w"); fwrite( data, sizeof( unsigned char), (int)SIZE, fp); fclose(fp); free(data); return 0; }

  • エラーがないのに正常に動かない

    以前質問したのものです。 アドバイス等いただき、プログラムを修正しエラーをなくしました。 しかし、プログラムが動きません。。。 プログラムの動作は CSVファイルを読み込んで、処理をする。 CSVファイルは 単語1,数値データ 単語2,数値データ のようになっており、 これをsの配列に格納したいと思っています。 プログラムの内容は #include<stdio.h> #include <string.h> int main(void) { FILE *fp; char s[5][1000][2][256]; char tp[256]; char *ttp; int i=0,ii=0; if((fp=fopen("out1.csv","r"))==NULL){ printf("ファイルオープンできませんよ\n"); return -1; } while(fgets(tp,256,fp)!=NULL){ ttp=strtok(tp,","); strcpy(&s[0][ii][i][0],ttp); puts(&s[0][ii][i][0]); while (ttp != NULL ) { i++; ttp=strtok(NULL,","); if (ttp != NULL ){ strcpy(&s[0][ii][i][0],ttp); puts(&s[0][ii][i][0]); }}i=0; ii++;if(ii>=1000)break; } return(0); } です。 わけがわからなくなりました(泣 どこが原因なのかも書いていただけるとありがたいです。

  • 二次元配列のプログラミングが分かりません

    センサからは常に「#(ONかOFFが16)CR」全部で18個の情報が送られてきます。ONは1、OFFは0を返します。 この情報20回分を二次元配列に格納し、排他的論理和を取るプログラムを考えています。 *************************************** 例3回の場合 1回目#1101110000000111CR 2回目#0010110101110100CR 3回目#0110010100010101CR これを縦に排他的論理和を取っていきます。 まず1回目と2回目の排他的論理和をとる 次に2回目と3回目の排他的論理和をとる 最後に全部で1がいくつあったのかを表示 **************************************** このようなプログラムを書きたいです。どのように書いたらいいでしょうか。 <今できているプログラムは以下です> int main(void) { int i=1; int a=0; int A[20][18]; int b,c =0; char* Buffer; FILE *fp1; Buffer = (char*)calloc(1024,sizeof(char)); char port1[10]; sprintf(port1,"COM6"); fp1 = fopen("result.txt","w"); // ファイルを開く /*ポート設定省略*/ /* 配列の初期化*/ for(b=0;b<20;b++){ for(c=0;c<18;c++){ A[b][c]=0; fprintf(fp0,"%2d",A[b][c]); } } fclose(fp0); /********************************* 数を合わせる #が入ったら読み込み残りの17を拾う *********************************/ do{ CommPort1->ReadBytes((unsigned char*)Buffer,1); }while(*Buffer !='#'); CommPort1->ReadBytes((unsigned char*)Buffer+1,17); //残りの17byteを読み込む CommPort1->FlushCommPort(); //データの送受信 for(int i=0;i<20;i++){ //20回分のデータを読みこみ、テキスト出力 tuushin(Buffer); n++; fprintf(fp1,"%d=%s \n",n,Buffer); } fclose(fp1); return 0; } /**************************************************** 通信する関数 「#(ONかOFFが16個)endコード」、計18からなる文字列を読み込み表示 ****************************************************/ void tuushin(char*Buffer) { CommPort1->ReadBytes((unsigned char*)Buffer,18); CommPort1->FlushCommPort(); printf("%s\n",Buffer); } どのようにかけばいいのか分からないので、教えてください。

  • C言語で複数列のデータを1列のみ読み込みたい

    行m列の任意のデータの処理を行うプログラムで, 列ごとの統計を行うためにm列目のデータを取り出したいのですが,うまくいきません. どのようなコードを書けばいいでしょうか? 自分で作ってみたのは以下のようなプログラムです(ファイルを開いて→m列目の読み込みの部分) EOFを使っているためか,行数のiには全データ数が入ってしまいます. void main (void) { FILE* fp; int i, j; i=0, j=0; char FilePath[500]; char Folder[100]; char File[50]; printf("Folder Name:"); scanf("%s",&Folder); printf("File Name:"); scanf("%s",&File); sprintf(FilePath,"%s/%s",Folder,File); if(( fp = fopen (FilePath,"r")) == NULL){ printf("cannot open '%s'\n", FilePath); exit(1); } //ここまではうまく動きます while (fscanf(fp, "%lf", &A[i][0]) != EOF{ i++; } while (fscanf(fp, "%lf", &A[0][j]) != EOF){ j++; } printf("A[%d][%d]", i, j); int n, m;              //n,mはこの後for文で使いたいので登場してもらいました printf("input 'n':"); scanf("%d", &n); printf("input 'm':"); scanf("%d", &m); }

  • テキストファイルの同期

    はじめまして、超初心者プログラマのmoominといいます。 ファイルの同期プログラムに関して質問があるのですが、 あるテキストファイルを、他のディレクトリのテキストファイルとを 常に同期をするプログラムを作成しています。 これが作成したソースです。 ------------------------- #include "stdafx.h" #include <stdio.h> #include <windows.h> int _tmain(int argc, char *argv[]) { FILE *fp,*copy; int buffer; fp=fopen("○○○/×××.txt","rb"); copy=fopen("aaa/fff.txt","wb"); for(int i=1;i>0;i++){ fread(&buffer,sizeof(buffer),1,fp); fwrite(&buffer,sizeof(buffer),1,copy); if(feof(fp)){ fclose(fp); fclose(copy); } } return 0; } VC2008を利用して作成していますが、 一度きりの同期なら可能なのですが、 常に同期するというプログラムがわかりません。 どう変えればよいでしょうか?

  • 構造体の動的メモリについて

    #include <stdio.h> #include <stdlib.h> #include <string.h> #define NUM 10 /*生徒数*/ typedef struct data { int num; /*従業員番号*/ char name[16]; /*名前*/ int jap; /*国語の点数*/ int math; /*数学の点数*/ }data; int main(void) { data test[NUM]; /*生徒のデータ*/ FILE *fp; /*ファイル操作用*/ int i; /*配列インデックス*/ int count; /*データ分割用*/ char s[100]; /*データ読み込み用*/ char *token; /*データ分割用*/ char *data[6]; /*分割データ保存用*/ fp = fopen ("data1.txt","r");        for (i=0; i<NUM; i++){ fgets (s, sizeof(s), fp); /*dataファイルから1行読み込み*/ token = strtok(s, ","); /*読み込んだデータを","で分割する*/ count=0; while (token != NULL){ data[count] = token; /*分割したデータを配列へ入れる*/ token = strtok(NULL,","); count++; } test[i].num = atoi(data[0]);       strcpy (test[i].name, data[1]); test[i].jap = atoi(data[2]); test[i].math = atoi(data[3]); } fclose(fp);       } このプログラムを構造体へのポインタの配列で管理するように変えたいのですが、どのように変更すればいいのでしょうか。 条件として、個人データを格納するメモリ領域とポインタの配列のメモリ領域は動的に確保します。 初心者でよくわからないので詳しく教えていただけると助かります。よろしくお願いします。

  • C言語の型変換(int~short)について

    Renesas HEWで、平均値を求める下記の様なプログラムを書いています。 unsigned short data[100] ; unsigned int total ; unsigend short avg_short ; unsigend int avg_int ; for (i=0; i<100 ; i++) {total += data[100];} avg_short = (short) (total / 100) ; avg_int = total / 100 ; とした場合、avg_intには、平均値が32bit(上位16bit=0)で格納されますが、 avg_shortは、0 が格納されます。 avg_intの下位16bitだけを格納するには、どうしたらよいのでしょうか?