• ベストアンサー

変数の値が勝手に変化する原因

以下のようなプログラムを書きました。(一部省略) data2[8] = '\0'; の行が実行された後になぜかgの値が1から0に変化してしまいました。 勝手に変数の値が変化しており、原因が把握できていません。 この原因として考えられることがあれば教えていただけないでしょうか? よろしくお願いします 以下、書いたプログラムです。 char data2[8]; FILE* fp; int g; int main{ fread(data2,8,1,fp); data2[8] = '\0';    ←ここでgの値が変化します。 fread(data2,8,1,fp); data2[8] = '\0'; return 0; }

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

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.1

> char data2[8]; と宣言したら、 data2[0]~data2[7] までの8個が確保されます。 data2[8]にアクセスした場合の結果はどうなるかわかりません。 他の言語では、範囲外エラーになったり、自動で拡張されたりするのですが、Cではその様な処理を行いません。 添字の範囲の管理はプログラマの責任です。 以上、C言語の基本です。忘れないでくさい。

saterain20
質問者

お礼

初歩的なミスですか。ありがとうございます。 なくすとうまくいきました。

その他の回答 (2)

  • adasnt
  • ベストアンサー率44% (69/154)
回答No.3

皆さんがおっしゃるように,data2[8]は間違いで,こうしたければ char data2[9]; <=9バイト確保 fread(data2,8,1,fp); <=8バイト読み込み data2[8]='\0'; <= 9バイト目をNULLに. とすべきでしょう. プログラムメモリ上では,data2が8バイト,その直後にg が割り当てられているようで, data2[8]はgの4バイトの一部にあたるのだと思います.だから,gの値が変わってしまう. 自分のプログラムを破壊しているということですね. この場合,自プログラム内のメモリにアクセスしているのでOSはエラーを返さないのです. もちろん,破壊した部分がデータではなく,プログラム部分であれば,破壊されたプログラムによってCPUがそれを実行できない場合は,エラーが起こりプログラムが異常終了します.

saterain20
質問者

お礼

初歩的なミスですか。ありがとうございます。 なくすとうまくいきました。

  • gao3967
  • ベストアンサー率28% (29/100)
回答No.2

char data2[8];と宣言した場合、data2の[]内は0~7までが有効です なので、data2[8] = '\0';は間違い

saterain20
質問者

お礼

初歩的なミスですか。ありがとうございます。 なくすとうまくいきました。

関連するQ&A

  • 警告 ”値が割り当てられていないローカルな変数~”について

    以下のコード1では、”値が割り当てられていないローカルな変数 'key' に対して参照が行われました。”という警告が出ますが、コード2では出ません。 コード2でも値が割り当てられていないと思うのですが、どうして警告が出ないのでしょうか? お分かりの方、お教えくだい。 あと、かなり省略してしまったので、意味の無いコードになってしまいましたが、この2つのコードでkeyの意味合いはどう違うのでしょうか? よろしくお願いいたします。 <コード1> int in_dt() { int *key; scanf( "%d", key );///ここで警告が出る return 1; } int main( void ) { int code; code = in_dt( ); return 0; } <コード2> int in_dt( int *key) { scanf( "%d", key ); return 1; } int main( void ) { int code,key; code = in_dt( &key); return 0; }

  • 平均値フィルタについて・・・・・・・・

    #include<stdio.h> #include<stdlib.h> #define X_SIZE 512 #define Y_SIZE 512 unsigned char DATA[Y_SIZE][X_SIZE]; unsigned char O_DATA[Y_SIZE][X_SIZE]; char input_file_name[256]=”Lenna.raw”; char output_file_name[256]=”Lenna_out.raw”; void heikin(){ int x,u; int temp; for(y=1;y<Y_SIZE-1;y++){ for(x=1;x<X_SIZE-1;x++){ temp=・・・・・・・・・・・・・・・・・ ; O_DATA[x][y]=(unsigned char)temp; } } } Int main (){ FILE*fp; If((fp=fopen(input_file_name,”rb”))==NULL){ Printf(“ファイルオ-プンエラ-\n”); Return 1; } Fread(DATA,sizeof(DATA),1,fp); fclose(fp); heikin(); if((fp=fopen(output_file_name,”wb”))==NULL{ printf(“ファイルオ-プンエラ-\n”); return 1; } Fwrite(O_DATA,sizeof(O_DATA),1,fp); Fclose(fp); Return 0; } 自分でプログラムを作って練習しているのですが、このソースコードで入力画像を読み込んで、平均値フィルタをかけ、Lenna_out.rawに書き出そうとしているのですが、・・・・・・の箇所には公式を当てはめていけばいいんでしょうか?? すみませんがよろしくお願いします。。。。。。

  • 画像処理について・・・・・・・・・・・

    #include<stdio.h> #include<stdlib.h> #define X_SIZE 512 #define Y_SIZE 512 unsigned char DATA[Y_SIZE][X_SIZE]; unsigned char O_DATA[Y_SIZE][X_SIZE]; char input_file_name[256]=”Lenna.raw”; char output_file_name[256]=”Lenna_out.raw”; void heikin(){ int x,u; int temp; for(y=1;y<Y_SIZE-1;y++){ for(x=1;x<X_SIZE-1;x++){ temp=・・・・・・・・・・・・・・・・・・・・・・・・; O_DATA[x][y]=(unsigned char)temp; } } } Int main (){ FILE*fp; If((fp=fopen(input_file_name,”rb”))==NULL){ Printf(“ファイルオ-プンエラ-\n”); Return 1; } Fread(DATA,sizeof(DATA),1,fp); fclose(fp); heikin(); if((fp=fopen(output_file_name,”wb”))==NULL{ printf(“ファイルオ-プンエラ-\n”); return 1; } Fwrite(O_DATA,sizeof(O_DATA),1,fp); Fclose(fp); Return 0; } ソースコードをやっているのですが、後、・・・・・・・・・の所を入力して完成なんですが、苦戦してます。 処理の内容としましては、 1、入力画像Lenna.rawを読み込んで、 2、平均値フィルタをかけ、 3、Lenna_out.rawに書き出す(保存する)したいんですが、公式みたいなのを入れればいいのでしょうか? すみませんが、お願いします。

  • プログラム(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字までなので構造体の宣言は抜いてしましました) 。

  • ファイルの内容の表示

    実行時のコマンドライン引数で指定したファイルの内容を、行番号付きで画面に表示するプログラムを作る という問題です。ヒントも与えられています。 行番号付きの表示、コマンドライン引数の利用。両者を組み合わせればできるはずだ >  main関数の引数にargcとargvを指定して、コマンドライン引数をファイル名として利用する。キーボード入力を促す文(プロンプト)や改行チェックは不要なので書かないこと >  コマンドライン引数が指定されない場合は、メッセージを表示してプログラムを終了 >  ファイルの内容を画面表示する処理は、ユーザー定義関数put_file_contentsに記述する。仮引数には文字型のポインタ変数をひとつ指定し、ファイル名を受け渡せるようにする。put_file_contents自体の型は整数型(int)で、正常終了なら返り値0を返すこと。 行番号付きのプログラム#include<stdio.h> > int put_file(char *filename); > > int main() > { > char line[50]; > char *ptr; > > printf("ファイル名を入力:"); > fgets(line,sizeof(line),stdin); > ptr = line + strlen(line) - 1; > if(*ptr == '\n') { > *ptr = '\0'; > } > > put_file(line); > > return 0; > } > > int put_file(char *filename) > { > FILE *fp; > char buf[100]; > int line_no; > > fp = fopen(filename,"r"); > if (fp == NULL){ > printf("%sを開けません\n",filename); > return 1; > } > line_no = 1; > while (fgets(buf,sizeof(buf),fp) != NULL){ > printf("%3d: ",line_no); > printf("%s",buf); > line_no++; > } > fclose(fp); > > return 0; > } で、コマンドライン引数のプログラムは#include<stdio.h> void write_key_inputs(char *filiname); int main(int argc, char *argv[1]) { write_key_inputs(argv[1]); return 0; } void write_key_inputs(char *filename) { FILE *fp; char buf[100] ; fp = fopen(filename,"w"); while(fgets(buf, sizeof(buf),stdin) != NULL) { fputs(buf, fp); } fclose(fp); return ; } です。これらを組み合わせて少しいじると出来るみたいなのですが、できていません。ちなみに私が考えたプログラムは #include<stdio.h> int put_file_contents(char *filename); int main(int argc,char *argv[]) { int i; if(argc == 1){ printf("コマンドライン引数がありません\n"); return 1; } for(i = 0;i<argc;i++) printf("argv[%d]は「%s」です\n",i,argv[i]); put_file(i); return 0; } int put_file(char *filename) { FILE *fp; char buf[100]; int line_no; fp = fopen(filename,"r"); line_no = 1; while (fgets(buf,sizeof(buf),fp) != NULL){ printf("%3d: ",line_no); printf("%s",buf); line_no++; } fclose(fp); return 0; } です。コマンドライン引数は表示されるのですが、行番号が表示されません。どうしたらいいでしょうか??

  • 変数の値がおかしくなる

    以下のようなプログラム(DLLとEXE)を書いたのですが、変数の値がおかしくなる(●参照)箇所があります。原因がお分かりになりましたら、ご回答をよろしくお願い致します。 ●mkdll.cppの、sub1()の(※1)までは、input[]が正しい値で入っているが、(※2)で値がおかしくなる。(※1)から(※2)までで、input[]は参照するだけです。 ---test.cpp(EXE)--- … main(){ int input[10],output[10]; int err; CDLL DLL; err = DLL.func(input,output); … return(0); } ---test.cpp End--- ---mkdll.h(DLL)--- … class __declspec(dllexport) CDLL{ public: int func(int *input, int *output); private: int sub1(int *input, int *output); int sub2(int in, int out); … }; ---mkdll.h End--- ---mkdll.cpp(DLL)--- #include "mkdll.h" … int CDLL::func(int *input, int*output){ int i; int error; error = sub1(input, output); return(error); } int CDLL::sub1(int *input, int *outout){ int i; int in1, in2, out1, out2; int err; //(※1) for(i=0; i<5; i++){ err = 0; in1 = input[i*2]; in2 = input[i*2+1]; //(※2) err = sub2(in1, out1); if(err != 0) return(err); … } } … ---mkdll.cpp End---

  • C言語、fgetcを利用しファイルの内容を変数に

    C言語について質問です C言語のfgetcを利用しファイルの内容を変数にいれてそれを返す関数を作っているのですがうまくいきません <!--以下ソース--> char *file_get_contents(char *filename){ FILE *fp; int c; char *return_str; if((fp=fopen(filename,"r"))==NULL) return NULL; while((c=fgetc(fp))!=EOF ){ sprintf(return_str,"%c",c); } fclose(fp); return return_str; } 誰か理由と改善方法を教えてください!

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

    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; }

  • 段落毎に配列に挿入するには?

    C++の基本的な配列でわからないことがあります。 例えば以下のような,3段落があるテキストファイルを用意しておき, -------------- //abc.txt abcde fghij klmno -------------- 用意した配列char data[3][20]へ, 上から順番にdata[0]に"abcde",data[1]に"fghij",data[2]に"klmno"を挿入したいです。 とりあえず1行だけ,以下のようなプログラムで出力表示できました。 #include <string> #include <iostream> using namespace std; int main() { char cir_data[3][20]; string filename("abc.txt"); FILE* fp = fopen( filename.c_str(), "r" ); fgets(data[0], 20, fp); cout << data[0] << endl; fclose(fp); return 0; } 結果は, -------------------- abcde -------------------- となったので,2・3番目もforループでできるかなと思ったら,良い結果が出ません。 以下は間違えているプログラムです。 int main() { char cir_data[3][20]; int i; string filename("abc.txt"); FILE* fp = fopen( filename.c_str(), "r" ); for(i=0; ; ){ fgets(cir_data[i], 20, fp); if(strlen(cir_data[i])<3) break; if(cir_data[i][0] != '/') i++; cout << cir_data[i] << endl; } fclose(fp); cout << "i = " << i << endl; return 0; } 結果は文字化けしてます。 何回ループしたか,iも出力してみましたが,なぜか6回カウントされています。 どこが誤っているのかわからず困っています。

  • C言語による構造体の値渡しについて

    以下プログラムを作成しました。 1.read_file関数によりファイルを読み込み。 2.avg_kokugo関数により、国語の平均点を出す。 という流れで組まれているのですが、 1.read_file関数実行時に、dat構造体を渡しています。 2.read_file関数内で、fscanfによる読み込みを行い、dat[i].name,&dat[i].kokugo,&dat[i].sansuに格納しているみたいに感じます。 ここで、疑問なのが、 「構造体を値渡しでdatをread_file関数に渡してる」と思っているのですが、 「read_file関数から、値渡しで渡された構造体datに、値を格納することはできるのでしょうか?」 本を参考にして勉強していたのですが、 「構造体は、値渡しの時に読み込みはできるが、更新はできない」 と書かれていたのです。(ポインタ参照渡しの時は可能。) なぜ今回、read_file関数から、構造体datに値の格納ができるのでしょうか? 更新と新規格納は意味が異なるからなのでしょうか? ご教授よろしくお願いします。 <ソース> #include <stdio.h> //グローバル #define FNAME "test.txt" struct score{ char name[20]; int kokugo; int sansu; }; int read_file(struct score dat[],int n); float avg_kokugo(struct score dat[],int n); int main(void){ struct score dat[3]; int ret; float kokugo; float sansu; ret= read_file(dat,3); if(ret <0){ return 0; } kokugo = avg_kokugo(dat,3); printf("国語の平均 %.1f\n",kokugo); return 0; } int read_file(struct score dat[],int n){ FILE *fp; //ファイルポインタ int i; fp=fopen(FNAME,"r"); if(fp==NULL){ printf("ファイルをオープンできませんでした。\n"); return -1; //-1によるプログラム強制終了 } //データ読み込み i=0; //datに保存していく。 while((fscanf(fp,"%s%d%d",dat[i].name,&dat[i].kokugo,&dat[i].sansu)) != EOF){ i=i+1; //ファイル件数読み込み } fclose(fp); return 0; } float avg_kokugo(struct score dat[],int n){ int sum; //合計 float answer; int i; sum=0; for(i=0;i<n;i++){ sum = sum + dat[i].kokugo; } //平均点を求める answer =(float)sum / (float)n; return answer; }