メモリが"read"になることができませでした。

解決


きょん  2005-05-13 21:43:17  No: 57396

「C言語関数の使い方+作り方」という本のP.185、getcharとputcharを使用した一般的なフィルタプログラムの原型を示すプログラムを書いてある通りに入力し、コンパイルもビルドもエラーが出ないのに、実行するとアプリケーションエラーが発生し、実行できません。
使用ソフトはVC++6.0、OSはwin2000です。

ソース
-------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

unsigned char HalfToHex(int x)
{
  static unsigned char str[] = {
    '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  x &= 0x0f;
  return str[x];
}

void OperationError(char *pstr)
{
  fprintf(stderr,pstr);
  exit(1);
}

int main(int argc,char *argv[])
{
  FILE *pfile;
  int n,count = 0;
  if(argc > 3 || !strcmp(argv[1], "/?") || !strcmp(argv[1],"-?"))
  {
    OperationError("Dump プログラム\n\n"
      "起動方法:Dump 入力ファイル名 [ > 出力ファイル名]\n");
  }
  if((pfile = fopen(argv[1],"rb")) == NULL)
    OperationError("入力ファイルを開けませんでした。\n");
  while((n = fgetc(pfile)) != EOF){
    fputc(HalfToHex((n & 0x0f) >> 4),stdout);
    fputc(HalfToHex(n & 0x0f),stdout);
    fputc(' ',stdout);
    if(!(++count % 24))
      fputc('\n',stdout);
    else if(!(count % 8))
      fputc(' ',stdout);
  }
  fclose(pfile);
  return 0;
}
----------------------------------------------------
デバッグに表示されるエラー
・'C:\WINNT\system32\ntdll.dll' をロードしました、合致するシンボル情報は見つかりませんでした。
・'C:\WINNT\system32\KERNEL32.DLL' をロードしました、合致するシンボル情報は見つかりませんでした。
・例外処理 (初回) は ***.exe にあります: 0xC0000005: Access Violation。
・プログラム 'C:\DOCUMENTS AND SETTINGS\***\***\***\Debug\***.exe' はコード 0 (0x0) で終了しました。

お願いします。


よん  2005-05-13 21:54:49  No: 57397

まずはステップ実行やprintfを使って
どこで落ちているのか
意図どおりの動作をしているか
を確認しましょう。


きょん  2005-05-13 22:08:43  No: 57398

早速返答ありがとうございます。
とりあえず言われた通りステップインで実行をしてみたところ、

dodwords:
        mov     eax,[edx]

の次で
「ハンドルされていない例外は***.exeにあります:0xC0000005:Access Violation。」
と出ました。


よん  2005-05-13 22:26:16  No: 57399

で、それはソースのどの部分ですか?
混合モードではなく、ソースの方でステップ実行できませんか?


きょん  2005-05-13 22:29:23  No: 57400

なんどもすいませんです。

if(argc > 3 || !strcmp(argv[1], "/?") || !strcmp(argv[1],"-?"))
の部分でエラーが発生しているようです。


WIZ  2005-05-13 22:34:06  No: 57401

可能性の1つを書きます。はずしていたらごめんなさい。

>  if(argc > 3 || !strcmp(argv[1], "/?") || !strcmp(argv[1],"-?"))

引数のエラーチェックが甘いので、引数無し(argc == 1)でも実行しようとして
しまいます。すると、

>  if((pfile = fopen(argv[1],"rb")) == NULL)

上記で、存在しない(不正な)ポインタ argv[1] を参照しているので、ここで
アプリケーションエラーになるのではないかと思います。
ちゃんと「Dump 入力ファイル名」の形で実行していますか?
また引数チェックは以下のようなコードにすべきです。(引数は1つですよね?)

    if(argc != 2 || !strcmp(argv[1], "/?") || !strcmp(argv[1],"-?"))

あと、本題には関係無いですけど

>       fputc(HalfToHex((n & 0x0f) >> 4),stdout);

上記は間違いで、以下のようにすべきだと思います。

        fputc(HalfToHex((n & 0xf0) >> 4),stdout);


WIZ  2005-05-13 22:40:29  No: 57402

# 更新(リロード)してから書き込めばよかった・・・。

> if(argc > 3 || !strcmp(argv[1], "/?") || !strcmp(argv[1],"-?"))
> の部分でエラーが発生しているようです。

やはり引数無しで「Dump」って実行していませんか?
argc == 1 だと !strcmp(argv[1], "/?") を評価しようとして、argv[1] に
アクセスして Access Violation になっているのだと想像します。


きょん  2005-05-13 22:40:48  No: 57403

WIZさん、よんさんありがとうございます。
うまくいきました。
これにて解決です。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加