0

今日書いたCプログラムのメモリデバッグにDr.Memoryを使用しています。MinGWのgccでコンパイルされたこのプログラムは、デバッガーgdbから実行した場合にのみ機能するため、メモリエラーを想定しています。Dr.Memoryから返されたresults.txtファイルは次のようなものです。

Dr. Memory version 1.5.0 build 5 builton Aug 31 2012 16:19:51
Application cmdline: ""c:\Users\Lincoln\Desktop\USACO\gift1.exe""
Recorded 63 suppression(s) from default c:\Program Files\Dr. Memory/bin/suppress-default.txt

Error #1: UNINITIALIZED READ: reading register eflags
# 0 replace_memcmp               [d:\derek\drmemory\withwiki\trunk\drmemory\replace.c:557]
# 1 parseInputs                  [c:\Users\Lincoln\Desktop\USACO/gift1.c:55]
# 2 main                         [c:\Users\Lincoln\Desktop\USACO/gift1.c:126]
Note: @0:00:00.473 in thread 3824
Note: instruction: jnz    $0x7388a607

Error #2: UNINITIALIZED READ: reading register eax
# 0 parseInputs               [c:\Users\Lincoln\Desktop\USACO/gift1.c:55]
# 1 main                      [c:\Users\Lincoln\Desktop\USACO/gift1.c:126]
Note: @0:00:00.473 in thread 3824
Note: instruction: test   %eax %eax

Error #3: UNINITIALIZED READ: reading register esi
# 0 replace_memcmp               [d:\derek\drmemory\withwiki\trunk\drmemory\replace.c:556]
# 1 parseInputs                  [c:\Users\Lincoln\Desktop\USACO/gift1.c:55]
# 2 main                         [c:\Users\Lincoln\Desktop\USACO/gift1.c:126]
Note: @0:00:00.474 in thread 3824
Note: instruction: movzx  (%esi,%ecx,1) -> %edi

Error #4: UNADDRESSABLE ACCESS: reading 0x00000004-0x00000005 1 byte(s)
# 0 replace_memcmp               [d:\derek\drmemory\withwiki\trunk\drmemory\replace.c:556]
# 1 parseInputs                  [c:\Users\Lincoln\Desktop\USACO/gift1.c:55]
# 2 main                         [c:\Users\Lincoln\Desktop\USACO/gift1.c:126]
Note: @0:00:00.474 in thread 3824
Note: instruction: movzx  (%esi,%ecx,1) -> %edi

これを読む方法や、プログラムの修正をどこから始めればよいのかわかりません。これらのエラーメッセージはどういう意味ですか、どうすれば修正できますか?

編集:これは私のコードです:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>

struct personsData {
    char * name;
    int accountMoney, receivedMoney, numAquaintances;
};

void parseInputs( FILE * fin, int NP, struct personsData * person ) {

    int i;
    for ( i = 0; i < NP; i ++ )
        fscanf( fin, "%s", person[i].name );

    char * tempName_1;
    while ( !feof( fin ) ) {

        tempName_1 = malloc ( sizeof( char ) * 15 );
        fscanf( fin, "%s", tempName_1 );

        int index = 0;
        while ( memcmp( tempName_1, person[index].name, 15 ) != 0 )
            index ++;
        free( tempName_1 );

        fscanf( fin, "%d %d", &person[index].accountMoney, &person[index].numAquaintances );

        int b;
        char * tempName_2;
        for ( b = 0; b < person[index].numAquaintances; b ++) {
            tempName_2 = malloc( sizeof( char ) * 15 );
            fscanf( fin, "%s", tempName_2 );
            i = 0;
            while ( memcmp( tempName_2, person[i].name, 15 ) != 0 )
                i ++;

            free( tempName_2 );

            person[i].receivedMoney += ( int ) floor( person[index].accountMoney / person[index].numAquaintances );
            person[index].accountMoney = floor( person[index].accountMoney / person[index].numAquaintances ) * person[index].numAquaintances;

        }
    }

}

int main() {

    FILE * fin  = fopen ("gift1.in",  "r");
    FILE * fout = fopen ("gift1.out", "w");

    int NP;
    fscanf( fin, "%d", &NP);

    struct personsData person[NP];
    int i;
    for ( i = 0; i < NP; i ++ ) {
        person[i].accountMoney = 0;
        person[i].receivedMoney = 0;
        person[i].numAquaintances = 0;
        person[i].name = ( char * ) malloc ( sizeof( char ) * 15 );
    }

    parseInputs( fin, NP, person );

    for ( i = 0; i < NP; i ++ ) {
        // print to output file (and also to console for development purposes
        fprintf( fout,  "%s %d\n", person[i].name, person[i].receivedMoney - person[i].accountMoney );
        printf(         "%s %d\n", person[i].name, person[i].receivedMoney - person[i].accountMoney );
    }

    for ( i = 0; i < NP; i ++ ) {
        free( person[i].name );
    }

    exit(0);
}

そしてこれは入力ファイルgift1.inです:

5
dave
laura
owen
vick
amr
dave
200 3
laura
owen
vick
owen
500 1
dave
amr
150 2
vick
owen
laura
0 2
amr
vick
vick
0 0
4

2 に答える 2

1

x86アセンブリに精通していますか?そうでない場合、これらのエラーのいくつかは説明するのが難しいでしょう。いずれにせよ、最初の行のように、コードのどの行がトレースバックに含まれているかを示しています。

# 0 replace_memcmp               [d:\derek\drmemory\withwiki\trunk\drmemory\replace.c:557]
# 1 parseInputs                  [c:\Users\Lincoln\Desktop\USACO/gift1.c:55]
# 2 main                         [c:\Users\Lincoln\Desktop\USACO/gift1.c:126]

一般に、これらのエラーは、初期化されていないメモリをNULLポインタに渡しmemcmp()、NULLポインタを逆参照していることを示しているように見えます。しかし、ミッチが示唆しているように、確実に言うにはコードを見る必要があります。

于 2012-11-16T00:34:03.873 に答える
0

DrMemory用のプログラムの準備に関するドキュメントを読んでいただけませんか。Visual Studioを使用したように見えるので、/ Zi、/MDまたは/Mt、/ Ob0、/Oy-を使用してコンパイルします。Dr Memoryは64ビットバイナリをサポートしていないため、32ビットであることを確認してください。

これにより、マシン命令ではなくソースコード行を含む出力が得られるはずです。

于 2012-11-16T00:36:43.953 に答える