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 isn't complaining about a leak - it's complaining that you're reading uninitialized memory and dereferencing an invalid pointer (the invalid pointer deref is crashing the program - at least under Valgrind).

We'd need to see UserGetID() and UserGetName() to have a hope of determining the bug in those (but that still might not be enough).

Based on your comment that mtmSuggestFriends is an object file that you don't have source for, my guess is that UsetGetID() and/or UserGetName() are passing invalid pointers to mtmSuggestFriends.

于 2012-05-04T07:03:23.397 回答
0

First, you are passing in an unassigned pointer user. Then your SuggestFriends() function called from UserGetID() is using this garbage pointer full of randomness as a real pointer which leads to the invalid read (SEGV)

You might find that setting "warnings as errors" (-Werr on gcc) would probably show you where you are doing unpredictable things.

于 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 回答