• ベストアンサー

メモリ関連のエラーを取り除くには・・

下記プログラムで、「.」区切りの文字列を 区切って返すプログラムを作成していますが、 メモリ関連のエラーが出てしまいます。 このようなメモリのエラーを取り除くには、何か 有用なツールでも使用すると楽になるのでしょうか。 自分で追いかけるのは大変なので・・ ちなみにmainの中で関数に渡したResultに結果が 入ってくるはずなのですが、mainの中で参照しようと するとエラーになってしまったので、bunkatu関数のなかで 表示するように一時的に変えております。 また、メモリの動的確保を行う場合には、同一のブロックで 行う必要があるのでしょうか。 #include <cstdlib> #include <iostream> using namespace std; int bunkatu (char *pOrg, int *iNum, char **Result); void main () { int iNum; char **Result = NULL; //結果格納用 bunkatu ("aaaa.fasdfafda.fa.dddd", &iNum, Result); } int bunkatu (char *pOrg, int *iNum, char **Result) { int iRtn; int iLocate = 0; int iTarget[10]; int iCount = 0; char *pTmp; pTmp = pOrg; if (*pTmp == '\0') { //空文字列の場合 iRtn = 1; } else { //空文字列以外の場合 //.を探す while (*pTmp != '\0') { //文字列終わりまで繰り返す。 if (*pTmp == '.') { //.が見つかった場合 iTarget[iCount] = iLocate; //.が見つかった添え字を保存 iCount++; //次の保存用にカウンタをカウントアップ } iLocate++; //詮索先を示すものをカウントアップ pTmp++; //詮索する位置を移動 } Result = (char **) calloc (iCount+1, sizeof (char *)); //切り出して表示 int iStart, iEnd; for (int j = 0; j < iCount+ 1; j++) { if (j == 0) { //はじめ iStart = 0; iEnd = iTarget[j] - 1; } else if(j < iCount){ //中間 iStart = iTarget[j - 1] + 1; iEnd = iTarget[j] - 1; } else if (j == iCount) { //最後 iStart = iTarget[j - 1] + 1; iEnd = strlen (pOrg) -1; } Result[j] = (char *) calloc (iEnd - iStart + 2, sizeof (char)); for (int k = 0; k < iEnd - iStart + 1; k++) { Result[j][k] = pOrg[iStart + k]; } Result[j][iEnd - iStart + 1] = '\0'; } *iNum = iCount; iRtn = 0; } //ちなみに~の部分 for (int i = 0; i < *iNum + 1 ; i++) { cout << Result[i] << endl; } for (int i = 0; i < *iNum + 1 ; i++) { free (Result[i]); } free (Result); return iRtn; }

  • otaks
  • お礼率53% (270/507)

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

  • ベストアンサー
  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.3

★アドバイス >メモリ関連のエラーが出てしまいます。  ↑  当然です。  文字列リテラル(文字列定数)に \0 を書き込んでいます。  場所はソースの『切り出し表示』の最後 >Result[j][iEnd - iStart + 1] = '\0';  ↑  ここです。→メモリ関連のエラーでるよ。 >何か有用なツールでも使用すると楽になるのでしょうか。  ↑  今回はエラーメッセージより直ぐに分かります。  ツールを使う前に文字列定数は定数なので書き換えできないという基本を  覚えておきましょう。エラーメッセージと共に。 >自分で追いかけるのは大変なので・・  ↑  なれる事です。 ・この程度のソースでは自分でバグを目で追いかけて探した方が早い気がしますけど。  ツールを使う前にソースデバッグ(ソースを見てデバッグ)を行って下さい。  あと適度にコメントしてどこまでは正常に動作しているのか、どこでエラーが発生  するのか特定します。 >ちなみにmainの中で関数に渡したResultに結果が >入ってくるはずなのですが…  ↑  ポインタを理解していないだけ。  『char **Result』を引数に渡して bunkatu 関数内でメモリを動的に確保したポインタを  Result にセットしたい場合は『&』演算子をつけて下さい。  つまり main() 関数にある bunkatu 関数の第3引数に注目。  bunkatu( "aaaa.fasdfafda.fa.dddd", &iNum, &Result );  ↑  あと第1引数は文字列定数ではなく文字型配列にコピーしてから渡します。  つまり main() 関数に  char string[] = "aaaa.fasdfafda.fa.dddd";    bunkatu( string, &iNum, &Result );  ↑  こうしないと実行時にエラーになります。  理由は一番最初にアドバイスしています。上参照。 >また、メモリの動的確保を行う場合には、同一のブロックで >行う必要があるのでしょうか。  ↑  動的確保したポインタをプログラム全体で管理していれば同一のブロック(関数)で  行う必要はありません。でもなるべく同一ブロックで処理した方が見やすいです。  またバグが入り込まずにすみます。 ・それから、ここの質問者さんのソースを覗いていつも思うのですが、1つの関数が  やたらに行数が多いですね。もっと複数の関数に処理を分けて見やすく記述した方が  いいですよ。  今回の場合は bunkatu() 関数が 73 行ありますけど。  処理内容も  (1)文字列の検索  (2)切り出し表示  (3)デバッグ用なのか『ちなみに~の部分』とか  この3つをサブ関数とかに分けておけばデバッグしやすくなりますよ。 ・今回はいろいろとバッグっていますね。 >Result = (char **) calloc (iCount+1, sizeof (char *));  ↑  この部分がおかしいです。  これにより bunkatu() 関数の引数宣言も変ります。  正しくは  *Result = (char **)calloc( iCount+1, sizeof(char*) );  と代入して  int bunkatu( char *pOrg, int *iNum, char ***Result )  と関数の引数宣言をして main() 関数では  bunkatu( string, &iNum, &Result );  と『&』を付けないと駄目です。 ・以上。今後の参考にして下さい。

otaks
質問者

補足

色々と実験してみて、エラーもなく実行できるように なりました。 問題部分はユーザ定義関数にダブルポインタを参照渡しして いなかったことだと思われます。 > 当然です。 > 文字列リテラル(文字列定数)に \0 を書き込んでいます。 の部分が理解できませんでした。 このままでも最終版のソースではエラー出ませんでした。 >この程度のソースでは自分でバグを目で追いかけて探した方が早い気がしますけど。 > ツールを使う前にソースデバッグ(ソースを見てデバッグ)を行って下さい。 大規模になったときにはどのようなツールを使うのでしょうか。

その他の回答 (5)

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.6

#2のzwiです。 >私が遭遇したメモリ関連のバグはとてもデバッガだけでは解決できそうもないものでした。(プログラムは私が作成したわけではなく、とても大規模で複雑なものでした。) >そこで、このような問題が再び起こったときに、何か便利なツールはないかという意図で質問した次第です。 基本的にカーネルでもからまない限り標準のデバッガでトレース可能だと思います。再現性さえあれば、スタック破壊やメモリ破壊の連鎖でも手間とテクニックで追跡可能です。 「デバッガだけでは解決できそうもない」のではなく、知識不足でデバッガが使いこなせていない可能性が高いのではないでしょうか? こういう本もありますから参考にされてはどうでしょう? http://www.amazon.co.jp/Windows%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E5%BE%B9%E5%BA%95%E8%A7%A3%E8%AA%AC-%E3%82%B8%E3%83%A7%E3%83%B3-%E3%83%AD%E3%83%93%E3%83%B3%E3%82%BA/dp/4891001860 http://www.amazon.co.jp/NET-Windows%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9E%E3%81%AE%E3%81%9F%E3%82%81%E3%81%AE%E3%83%87%E3%83%90%E3%83%83%E3%82%B0%E3%83%86%E3%82%AF%E3%83%8B%E3%83%83%E3%82%AF%E5%BE%B9%E5%BA%95%E8%A7%A3%E8%AA%AC-%E3%82%B8%E3%83%A7%E3%83%B3-%E3%83%AD%E3%83%93%E3%83%B3%E3%82%BA/dp/4891003529/ref=pd_sim_b_1/250-0399562-6461017 ちなみに高額な値段や海外ソフトでも問題なければ、高機能なデバッガやテストツールが販売されてます。 http://www.componentsource.co.jp/ese/features/debugging-testing/windows/index.html http://itpro.nikkeibp.co.jp/data/scate2.jsp?CID=020040010 これらも使いこなすには、高度な知識が不可欠です。

otaks
質問者

お礼

ご回答ありがとうございます。 たしかにデバッガの使い方に関しては、まだまだ 知識がたりません。 これから覚えていこうと思います。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.5

★返信です。 >なぜなくてもよいのでしょうか。  ↑  main() 関数を抜けるとメモリが自動的に解放されるためなくても良い。  これは fopen()、fclose() も同じです。  main() 関数を抜ける自動的にファイルをクローズします。 ・でも main() 以外ではプログラムが終了するまでは自動的にメモリもファイルも  クローズしません。よって main() でも私は対応をとるために free()、fclose() を  記述しています。他の関数では必要がなくなった時点で free()、fclose() しましょう。 >> 当然です。 >> 文字列リテラル(文字列定数)に \0 を書き込んでいます。 >の部分が理解できませんでした。  ↑  良く見たら calloc() でメモリを確保していますね。  それなら \0 を書き込んでも問題ないようです。  でも文字列定数を書き換えようとするとエラーダイアログなどが出ますよ。  例えば  char *str = "0123456789";    str[ 3 ] = 'A';  このようにするとエラーとなります。でも  char str[] = "0123456789";    str[ 3 ] = 'A';  これはエラーにはなりません。  文字列定数ではないので。 >大規模になったときにはどのようなツールを使うのでしょうか。  ↑  エラーダイアログが出たときに『デバッガ』でも起動すれば良い。  まずは『デバッガ』を使ってみる。 ・以上。

otaks
質問者

補足

ご回答ありがとうございます。 なぜfreeが要らないのかが分かりました。 ・他の関数に合わせる ・他人が見て誤解を招かない(mainだと必要ないと知らない人もいる) ためにもmainにもfreeを使ったほうがよいと思いました。 > 良く見たら calloc() でメモリを確保していますね。 > それなら \0 を書き込んでも問題ないようです。 calloc()でメモリを確保すると、その領域は文字列定数に なるのですか? いまいちその辺りが理解できてないのですが、 calloc()で動的にメモリ確保した所に値を代入したら、 まずかったでしょうか 質問ばかりで申し訳ありません。 >>大規模になったときにはどのようなツールを使うのでしょうか。 > ↑ > エラーダイアログが出たときに『デバッガ』でも起動すれば良い。 > まずは『デバッガ』を使ってみる。 私が遭遇したメモリ関連のバグはとてもデバッガだけでは解決 できそうもないものでした。(プログラムは私が作成したわけで はなく、とても大規模で複雑なものでした。) そこで、このような問題が再び起こったときに、何か便利な ツールはないかという意図で質問した次第です。

  • Oh-Orange
  • ベストアンサー率63% (854/1345)
回答No.4

★追記。 ・模範解答も載せておく。  コメントやソースを読み取って下さい。 #include <stdio.h> #include <stdlib.h> #include <string.h> // 分割 int mySplit( char *pBuff, int *iNum, char ***ppResult ) {  char **ppList;  char *pSeek;  char *pFind;  int iCount;    // ピリオドの数を数える  pSeek = pBuff;  for ( iCount = 0 ; (pFind = strchr(pSeek,'.')) != NULL ; iCount++ ){   pSeek = (pFind + 1);  }  if ( *pSeek != '\0' ){   iCount++;  }  // 空文字列なら終了  *iNum = iCount; // 個数をセット  if ( iCount == 0 ){   *ppResult = NULL;   return 0;  }  // 動的確保  if ( (*ppResult = ppList = (char**)calloc(iCount + 1,sizeof(char*))) == NULL ){   return -1; // メモリ不足  }  // 配列セット  pSeek = pBuff;  for ( *ppList++ = pSeek ; (pFind = strchr(pSeek,'.')) != NULL ; *ppList++ = pSeek ){   pSeek = pFind;   *pSeek++ = '\0'; // ピリオドを \0 に書き換え  }  if ( *pSeek != '\0' ){ // 最後がピリオドなら追加しない   *ppList++ = pSeek;  }  *ppList = NULL; // 最後に NULL セット  return iCount; // 正常(個数を返す) } // メイン関数 int main( void ) {  char string[] = "aaa.bbbb.ccccc.dddddd";  char **Result;  int i, iNum;    // 分割  mySplit( string, &iNum, &Result );  // 表示  for ( i = 0 ; i < iNum ; i++ ){   printf( "Result[%d] = %s\n", i, Result[i] );  }  printf( "iNum=%d\n", iNum );  // 解放  free( Result ); // なくても良い  return 0; } 解説: ・mySplit() 関数で分割します。この関数の戻り値は  0 以上…分割した個数(iNumと同じ)  0 以下…メモリ不足(Result=NULL保証)  0 なら…空文字列のため分割しなかった(iNum=0,Result=NULL保証)  となります。 ・以上。

otaks
質問者

補足

ご回答ありがとうございます。 >free( Result ); // なくても良い なぜなくてもよいのでしょうか。

  • zwi
  • ベストアンサー率56% (730/1282)
回答No.2

No.1の方の代わりに回答しますとポインタの扱いが大きく間違っている箇所があります。 bunkatu()関数を呼び出すときにResultを値渡しで渡しています。Resultのアドレスを渡してやらないとbunkatu()関数で書き換えて返すことができません。 ポインタのポインタを扱っているので混乱しているのだと思いますが、実体渡しなのか値渡しなのかを常に意識しましょう。

otaks
質問者

お礼

ご回答ありがとうございます。 指摘内容を考えてみます。

  • a-saitoh
  • ベストアンサー率30% (524/1722)
回答No.1

エラーを取り除くと言うよりは、エラーが起きないように1からちゃんと書きなおす、という方が近道だと思います。このプログラムだと。 まずは、 bunkatu()からResultを戻すところがなぜこれではダメなのか理解できるようになりましょう。

otaks
質問者

補足

ご回答ありがとうございます。 短いだろうと思ってアルゴリズムを考えつつやって しまったのが問題でした。 書き直そうとは思いますが、 >bunkatu()からResultを戻すところがなぜこれではダメなのか理解できるようになりましょう。 これがなぜだか分からないのです。 ご教授いただけますでしょうか。

関連するQ&A

  • プログラムのことで

    次のプログラムの変数の説明と処理の流れを素人でも理解できるように説明してもらえないでしょうか。 #include <stdio.h> #define MAX 128 int str_comp(char nx[], char ny[]){ int i, j, k=0; for(i=0; i<=MAX; i++){ if( nx[i]=='\0' ){ return 0; } else if( nx[i]==ny[0] ){ for( j=0; nx[i]==ny[j]; j++ ){ i++; } if( ny[j]=='\0' ){ return 1; } } } } int main(void) { char namex[MAX}; char namey[MAX}; int n; int i; printf("文字列x(64文字まで)? "); scanf("%s",namex); printf("文字列y(64文字まで)? "); scanf("%s",namey); n=str_comp(namex,namey); if(n==1){ printf("'%s'に'%s'は含まれます\n",namex,namey); } else if(n==0){ printf("'%s'に'%s'は含まれません\n",namex,namey); } return 0; } 実効結果 文字列x(64文字まで)? Katatsumuri  文字列y(64文字まで)? ta 'Katatsumuri'に'ta'は含まれます. エラーは出ないはずです。 よろしくお願いします。

  • strstrを利用しない文字列検索について

    キーボードから入力した文字列 str に対し, This is~の文字列中に str が出現するかどうかを判定して表示するプログラムを作成したいのですが、うまくコンパイルができません。 条件ですが、、、 ・forループを利用し、0文字目、1文字目と順に検索していく ・strstr関数およびstring.hを利用しない です。このプログラムをいじって教えてほしいです。 ややこしくて答えづらい質問かと思いますが、有識者の知恵を拝借したいです。よろしくお願いします。 #include <stdio.h> int main(void) { char str[256]; char s[] = "This is a pen. That is an apple."; int i,j,k,checker; printf("This is a pen. That is an apple.\n\n"); gets(str); for(j=0;j<256;j++) { for(i=j,k=0;str[k]!='\0';k++,i++) { if(str[k]==s[i]) { checker=1; } else { checker=0; } } } if(checker==0) { printf("NG!その文字列は含まれていません。\n"); } else { printf("OK!その文字列は含まれています。\n"); } }

  • ポインタのエラー?

    配列とポインタを使って多数桁の加算をするプログラムを作ったのですが、演算結果を表示した後にエラーが出てしまいます。初心者なので書式もばらばらで読みにくいと思いますが、お願いします。 #include <stdio.h> #include <stdlib.h> #define N 10 void main() { int *a,*b,*result,carry,i; a=(int *)calloc(N+1,sizeof(int)); b=(int *)calloc(N+1,sizeof(int)); result=(int *)calloc(N+1,sizeof(int)); /*配列aへの読み込み*/ for(i=1;i<N+1;i++) scanf("%d",&*(a+i)); *a=0; printf("入力された数値:"); for(i=1;i<N+1;i++) printf("%d",*(a+i)); printf("\n"); /*配列bへの読み込み*/ for(i=1;i<N+1;i++) scanf("%d",&*(b+i)); *b=0; printf("入力された数値:"); for(i=1;i<N+1;i++) printf("%d",*(b+i)); printf("\n"); /*配列resultの初期化*/ for(i=0;i<N+1;i++) *(result+i)=0; carry=0; /*result=a+bの演算*/ for(i=(N+1);i>=0;i--){ *(result+i)=*(a+i)+*(b+i)+carry; if(*(result+i)>=10){ *(result+i)-=10; carry=1; } else carry=0; } /*演算結果の表示*/ printf("和:"); for(i=0;i<N+1;i++) printf("%d",*(result+i)); printf("\n"); /*メモリ領域の解放*/ free(a); free(b); free(result); }

  • 配列のエラーが出る(opencv)

    3次元配列を用いて、ルックアップテーブルを作成しているのですが、下のようなエラーが出て困っています。 『○○○の 0x000000013f336f85 でハンドルされていない例外が発生しました: 0xC0000005: 場所 0xffffffffffffffff を読み込み中にアクセス違反が発生しました。』 いろいろ調べてみたのですが、私自身の力だけでは解読できません。 どうぞよろしくお願いします。 //LUTの作成 int ***LUT = new int**[180]; for(int i=0;i<180;i++){ LUT[i] = new int*[255]; } for(int i=0;i<180;i++){ for(int j=0;j<255;j++){ LUT[i][j] = new int[255]; } } for(int i = 0; i < 180; i++){ for(int j = 0; j < 255; j++){ for( int k = 0; k < 255; k++){ LUT[i][j][k]= 0; if(6 < i && i< 38){ if( 79 < j && j < 256){ if( 0 <= k){ LUT[i][j][k] = 1; } } } } } } //LUT作成終了 cvCvtColor(image3, image5, CV_BGR2HSV); IplImage* image5 = cvCreateImage(cvSize(640, 480), IPL_DEPTH_8U, 3); //if(hand == 0){ for(int i = 0; i < 480; i++){ for(int j = 0; j <680 ; j++){ //判定(LUT[ Hの値 ][ Sの値 ][ Vの値 ] ) if((LUT[(unsigned char)image5->imageData[( i * image5->widthStep + j) * 3 + 0]] [(unsigned char)image5->imageData[( i * image5->widthStep + j) * 3 + 1]] [(unsigned char)image5->imageData[( i * image5->widthStep + j) * 3 + 2]]) == 1){ printf("1\n"); } else{ printf("0\n"); } } } //LUT no atosyori for(int i=0;i<180;i++){ for(int j=0;j<255;j++){ delete[] LUT[i][j]; } } for(int i=0;i<180;i++){ delete[] LUT[i]; } delete[] LUT; よろしくお願いします。

  • 自作のstrcpyもどきがきちんと動作しません

    自作のstrcpyもどきがきちんと動作しません この前から、strcpyもどきを作っているのですがうまく動作しません。 strcpyもどきは 第一引数のバッファに第二引数の書式にしたがって、%sがあるところに第三引数の文字列を入れるという動作させるつもりです。 例として、 書式: TEST%%%sAIUEO 文字列: AB 希望する結果: TEST%ABAIUEO としてみたのですが、バッファの中身を見ると、ところどころTESTやAIUEOとあるのですが、変なデータが入ってしまうようで、 for文でバッファの中身をすべて0にしてみると、%から後が表示されなくなりました。 長文で申し訳ありませんが、ご教示よろしくお願いします. 呼び出し元 --------------------------------------------------- int main (){ char strbuf[50]; char str[]="AB"; strPaste(strbuf, "TEST%%%sAIUEO", str); printf("%s\n", strbuf); return 0; } 本体 --------------------------------------------------- int strPaste (char *buf, const char *format, const char *str){ int i,j,k, cflag; for(i=0, j=0, cflag=0; format[i] != 0; i++, j++){ if(cflag == 1){ if(format[i] == '%') buf[j] = '%'; if(format[i] == 's'){ for(k=0; str[k] != 0; k++, j++) buf[j] = str[k]; } cflag=0; continue; } if(format[i] == '%') cflag = 1; else buf[j] = format[i]; } return 0; }

  • debugエラーについて

    VisualC++初心者です。 力を貸してください。 内容はDEBUG ERRORで Stack around the variable "rp" was corrupted Stack around the variable "res" was corrupted とでてしまいます。 構造体等は省略しました。 #include <stdio.h> #include <stdlib.h> #define N 8 typedef struct{ int maxi,maxj,akarusa[N][N]; unsigned char *data; }RESULT; int bunkatsu(BMP *rp,BMP *wp); int keisan(BMP *rp,BMP *wp); RESULT *max(RESULT *res); /* 画像の取込 */ int ReadHeader(BMP *p,FILE *fp){ unsigned int size; fseek(fp, 0, SEEK_END); size = ftell(fp); fseek(fp, 0, SEEK_SET); fread(&p->Bmpf.bfType, sizeof(unsigned short), 1, fp); fclose(fp); exit(1); } fread(省略) return 0; } int ReadBmp(BMP *p,FILE *fp){ int dummy, byte, i, j, pixel; unsigned char *ReadBody=0; ReadHeader(p,fp); byte = p->Bmpi.biBitCount/8; dummy = (p->Bmpi.biWidth%4)?(4-(p->Bmpi.biWidth*byte)%4) : 0; pixel = ((p->Bmpi.biWidth)*byte+dummy)*p->Bmpi.biHeight; ReadBody = (unsigned char*)calloc(pixel,sizeof(char)); p->body = (unsigned char*)calloc(pixel,sizeof(char)); p->blue = (unsigned char*)calloc((pixel/byte),sizeof(char)); p->green = (unsigned char*)calloc((pixel/byte),sizeof(char)); p->red = (unsigned char*)calloc((pixel/byte),sizeof(char)); fread(ReadBody,1,pixel,fp); if(p->Bmpi.biBitCount == 8){ printf("\n"); for(j=0;j<p->Bmpi.biHeight;j++){ for(i=0;i<p->Bmpi.biWidth;i++){ p->blue[(p->Bmpi.biWidth+dummy)*j+i] =p->Rgbq[ReadBody[(p->Bmpi.biWidth+dummy)*j+i]].rgbBlue; p->green[(p->Bmpi.biWidth+dummy)*j+i] =p->Rgbq[ReadBody[(p->Bmpi.biWidth+dummy)*j+i]].rgbGreen; p->red[(p->Bmpi.biWidth+dummy)*j+i] =p->Rgbq[ReadBody[(p->Bmpi.biWidth+dummy)*j+i]].rgbRed; } } for(j=0;j<p->Bmpi.biHeight;j++){ for(i=0;i<p->Bmpi.biWidth;i++){ p->body[(p->Bmpi.biWidth+dummy)*j+i]=ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)+i]; } } } else if(p->Bmpi.biBitCount == 24 || p->Bmpi.biBitCount == 32){ for(j=0;j<p->Bmpi.biHeight;j++){ for(i=0;i<p->Bmpi.biWidth;i++){ p->blue[(p->Bmpi.biWidth+dummy)*j+i] = ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)*byte+i*byte]; p->green[(p->Bmpi.biWidth+dummy)*j+i] = ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)*byte+i*byte+1]; p->red[(p->Bmpi.biWidth + dummy)*j+i] = ReadBody[(p->Bmpi.biWidth+dummy)*(p->Bmpi.biHeight-1-j)*byte+i*byte+2]; } } } else{ printf("失敗\n"); exit(1); } free(ReadBody); return 0; } /* 480×480にする */ int bunkatsu(BMP *rp,RESULT *res){ int x,y,a=0; for(y=0;y<rp->Bmpi.biHeight;y++){ for(x=79;x<rp->Bmpi.biWidth-80;x++){ res->data[a] = rp->blue[y*rp->Bmpi.biWidth+x]+rp->green[y* rp->Bmpi.biWidth+x]+rp->red[y*rp->Bmpi.biWidth+x]; a++; } } return 0; } /* ブロック分けして各ブロックの明るさを計算する */ int keisan(BMP *rp,RESULT *res){ int b,c,x,y,i=0,j=0; for(y=0;(y+60)<rp->Bmpi.biHeight;y+=60){ for(x=0;(x+60)<(rp->Bmpi.biWidth-160);x+=60){ for(b=0;b<60;b++){ for(c=0;c<60;c++){ res->akarusa[i][j]+=res->data[(y+b)*rp->Bmpi.biWidth+(x+c)]; } } j++; } i++; } max(res); return 0; } /* 一番明るいブロックの特定 */ RESULT *max(RESULT *res){ int MAX1=0,MAX2=0,i=0,j=0; for(i=0;i<8;i++){ for(j=0;j<8;j++){ printf("[%d][%d]=%d",i+1,j+1,res->akarusa[i][j]); if(MAX1<res->akarusa[i][j]){ MAX1=res->akarusa[i][j]; res->maxi=i; res->maxj=j; } } printf("\n"); } printf("一番明るいブロックは[%d][%d]です\n",res->maxi+1,res->maxj+1); return 0; } int main(void){ BMP rp={0}; RESULT res={0}; FILE *fp; /* 画像の取り込み */ fp=fopen("LED1.bmp","rb"); ReadBmp(&rp,fp); res.data = (unsigned char*)calloc(rp.Bmpi.biWidth*rp.Bmpi.biHeight,sizeof(char)); fclose(fp); fp=0; bunkatsu(&rp,&res); keisan(&rp,&res); return 0; } です。よろしくお願いします。

  • プログラムの間違っている箇所が分かりません

    文字列の置換プログラムを作りたいのですが、下記のプログラムでは正常に動きませんでした。 例えば、「call」の「ll」を「sell」と変換しようとするとエラーがでてしまいます。 プログラミング初心者なので、どこが間違っているのかよく分からないです。 以下、問題のあるプログラムを記述します。 #include <stdio.h> void change(char *in, char *bef, char *af){     char tmp[100];     int i = 0, j = 0;     int flg=0;         for(i = 0; *(af + i) != '\0'; i++){         tmp[i] = *(af + i);     }     tmp[i] = '\0';     for(j = 0; *(in + j) != '\0'; j++){     if(flg == 0 && *(bef + j) == '\0'){             flg = 1;     }         if(flg == 1){             tmp[i++] = *(in + j);             tmp[i] = '\0';         }     }     for(j = 0; j<=i; j++){         *(in + j) = tmp[j];     } } int check(char *in, char *bef){       int i=0;     int flg=0;     while(*(bef+i)!='\0'){             if(*(in+i)=='\0' || *(in+i)!=*(bef+i)){             flg=1;             break;         }         i++;     }     return flg; } int main(){     char in[100];     char bef_ch[20];     char af_ch[20];     int i=0;     printf("文字列を入力して下さい。\n");     gets(in);     printf("置換したい文字列を入力して下さい。\n");     gets(bef_ch);     printf("置換後の文字列を入力して下さい。\n");     gets(af_ch);     while(in[i]!='\0'){         if(check(&in[i], &bef_ch[0]) == 0){             change(&in[i], &bef_ch[0], &af_ch[0]);         }         i++;     }     printf("置換結果を示します。\n");     printf("%s\n",in);     return 0; }

  • なぜエラーになるのかわかりません

    入力した文字列からthがいくつ含まれるのかというプログラミングを作りたいのですが>if( sentence[i] == 'th' )の部分で 「比較において定数が範囲外」というエラーがでてしまいます。eなどひとつの文字でならでないのですが・・・よくわからないので教えてください #include <iostream.h> main() { const int Max_Length = 80 ; char sentence[Max_Length] ; int count ; int th ; for(;;){ // 文字列の入力 cout << "\n 文字列を入力して下さい(英数字のみ) >> " ; cin.getline( sentence, Max_Length ) ; // 文字数を数える count = 0 ; while( sentence[count] != '\0' ){ count++ ; } //thの数を数える th = 0 ; for( int i = 0 ; i <= count ; i++ ){ if( sentence[i] == 'th' ) th++ ; } // 文字列の再表示と結果の表示 cout << "\n 文字列= " << sentence << endl ; if( th == 0 ) cout << "thは含まれません" << endl ; cout << "thの数は" << th << endl ; } }

  • プログラムを作ったのですがエラーメッセージが出ます

    原因がわかりません。他にもいくつか作ったのですが他のものはコンパイルします。 エラーメッセージ fatal error c1083 ソースファイルが開けません 因みに作ろうとしているプログラムは * ** *** **** ***** **** *** ** * を描画させるものです #include<stdio.h> main() { int i, j; int k; for(i=1; i<=9; i++){ if(i<5){ k=i; } if(i>=5){ k=10-i; } for(j=1; j<=k; j++){ printf("*"); } printf("\n"); } }

  • 単語の出現頻度を調べるプログラム

     ファイルからデータを読み込んで、単語の出現頻度を調べるプログラムを作ろうと考えて、下記のようなプログラムを書いてみました。 #include <stdio.h> #include <string.h> main() { struct data {char word[128]; int freq;} word_data[128]; char words[128]; char term[128]; int i=0; int nw=0; int j; char buff[128]; FILE *fp_in=fopen("data.txt","r"); while(fgets(fp_in,128,buff)!=EOF){ char buff[128]; int k; for(k=0;k<=128;k++){ printf("%s",buff); if(('A'<=buff[k] && buff[k]<='Z')||('a'<=buff[k] && buff[k]<='z')) term[i++]=buff[k]; else if(i>0) term[i]='\0';} for(j=0;j<nw;j++){ if(strcmp(term,word_data[j].word)==0) break; if(j==nw) {strcpy(word_data[j].word,term); word_data[j].freq=1; nw++;} else if(j!=nw) {word_data[j].freq++; i=0;} }} for(j=0;j<nw;j++) printf("%s %d",word_data[j].word,word_date[j].freq); return 0;} コンパイルは通ったのですが、実行しても画面に何も表示されません。原因は何処にあるのでしょうか?分かる方がいましたら、ご回答宜しくお願いします。

専門家に質問してみよう