1

valgrindでエラーを生成するコードのこの小さな部分で問題が発生しています。コードにコメントしてvalgrindを実行すると、メモリリークやエラーが発生しないため、このループが原因である可能性があります。

///Print the top users
    const char* str;
    for (int i = 0; i < count; i++) {
        if (FinalArray[i].Score == -1) {
            break;
        }

        int id = UserGetID(user);
        char* name = UserGetName(user);
        int finalID = UserGetID(FinalArray[i].user);
        char* finalName = UserGetName(FinalArray[i].user);

        assert(finalName!= NULL && name !=NULL);
        str = mtmSuggestFriends(id, name, finalID, finalName);

        if (str == NULL) {
            return MAIN_ALLOCATION_FAILED;
        }

//      fprintf(fileOutput, str);
    }

このループの後、成功を示す列挙型を返すだけです。

Valgrindのエラーは次のとおりです。

==8779== Use of uninitialised value of size 8
==8779==    at 0x4037C2: UserGetName (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x401FAC: SuggestFriends (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x402E6D: executeUserCommand (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x40281B: main (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779== 
==8779== Use of uninitialised value of size 8
==8779==    at 0x4037A0: UserGetID (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x401FC8: SuggestFriends (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x402E6D: executeUserCommand (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x40281B: main (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779== 
==8779== Invalid read of size 1
==8779==    at 0x403F1A: mtmSuggestFriends (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x401FEE: SuggestFriends (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x402E6D: executeUserCommand (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x40281B: main (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==  Address 0x9848B4458BB44589 is not stack'd, malloc'd or (recently) free'd
==8779== 
==8779== Process terminating with default action of signal 11 (SIGSEGV)
==8779==  General Protection Fault
==8779==    at 0x403F1A: mtmSuggestFriends (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x401FEE: SuggestFriends (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x402E6D: executeUserCommand (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779==    by 0x40281B: main (in /u1/023/mtm/ex2/RUN/mtm_isocial)
==8779== 
==8779== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 4 from 1)
==8779== malloc/free: in use at exit: 1,250 bytes in 93 blocks.
==8779== malloc/free: 455 allocs, 362 frees, 10,081 bytes allocated.
==8779== For counts of detected errors, rerun with: -v
==8779== searching for pointers to 93 not-freed blocks.
==8779== checked 122,512 bytes.
==8779== 
==8779== LEAK SUMMARY:
==8779==    definitely lost: 0 bytes in 0 blocks.
==8779==      possibly lost: 0 bytes in 0 blocks.
==8779==    still reachable: 1,250 bytes in 93 blocks.
==8779==         suppressed: 0 bytes in 0 blocks.
==8779== Reachable blocks (those to which a pointer was found) are not shown.
==8779== To see them, rerun with: --show-reachable=yes

関数ToStringUserは、const char *のmallocを返します。それで、それを正しく解放することを心配する必要はありませんか?

なぜこれが起こっているのか考えていますか?

forでこのコードを使用してstrを解放しようとしましたが、同じエラーと同じ量のメモリリークが発生し続けます。

free((char*) str); OR free((void*) str);

UserとgetIDおよびgetNameの構造体は次のとおりです。

struct User_t {
    char *Name;
    int ID;
    int Birth;
};
int UserGetID(User user) {
    return user->ID;
}
char* UserGetName(User user) {
    return user->Name;
}

ループの前に、次のコマンドで新しいユーザーを初期化します。

User user = FindUserPointer(setUser, id);

使用される関数は次のとおりです。

static User FindUserPointer(Set users, int ID) {
        assert(users!=NULL);
    User tmpUser = UserCreate("temp", ID, 99);
    if (tmpUser == NULL) {
        return NULL;
    }
    SET_FOREACH(User,Itrator1,users) {
        if (UserCompare(tmpUser, Itrator1) == 0) {
            UserFree(tmpUser);
            return Itrator1;
        }
    }
    UserFree(tmpUser);
    return NULL;
}
4

3 に答える 3

5

Valgrindはリークについて不平を言っていません-初期化されていないメモリを読み取っていて、無効なポインタを逆参照していると不平を言っています(無効なポインタの間接参照はプログラムをクラッシュさせています-少なくともValgrindでは)。

UserGetID()それらのバグを確認し、特定することを期待する必要がありますUserGetName()(ただし、それでも十分ではない可能性があります)。

mtmSuggestFriendsソースがないオブジェクトファイルであるコメントに基づいて、私の推測では、UsetGetID()および/またはUserGetName()に無効なポインタを渡していますmtmSuggestFriends

于 2012-05-04T07:03:23.397 に答える
0

まず、割り当てられていないポインタを渡しますuser。次に、SuggestFriends()fromで呼び出された関数はUserGetID()、ランダム性に満ちたこのガベージポインターを、無効な読み取りにつながる実際のポインターとして使用しています(SEGV

「警告をエラーとして」(-Werrgccで)に設定すると、予測できないことをどこで行っているかがわかる可能性があります。

于 2012-05-04T07:03:38.500 に答える
0
struct User_t {
char *Name;
int ID;
int Birth;
};
int UserGetID(User user) {
    return user->ID;
}

...そしてどこでUser定義されていますか?

于 2012-05-04T07:27:00.453 に答える