简体   繁体   English

在这个小的for循环中出现内存泄漏和valgrind错误?

[英]Memory leak and valgrind errors in this small for loop?

I'm having trouble with this small part of the code that generates errors in valgrind. 我在这部分代码中遇到了麻烦,该代码在valgrind中生成错误。 When I comment the code and run valgrind, I dont get any memory leak or error so this loop should be the cause: 当我注释代码并运行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);
    }

after this loop I simply return an enum stating success. 在此循环之后,我只返回一个声明成功的枚举。

Here are the errors in Valgrind: 以下是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

The function ToStringUser returns a malloc of const char*.. So I shouldnt worry about freeing it right? 函数ToStringUser返回const char *的malloc。因此,我不必担心释放它吗?

Any idea why is this happening? 知道为什么会这样吗?

I tried to free the str with this code in the for but I keep getting the same errors and the same amount of memory leaks: 我尝试使用for中的此代码释放str,但我不断收到相同的错误和相同数量的内存泄漏:

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

Here is the struct of the User and the getID and getName: 这是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;
}

Before the loop I initialize a new User with this: 在循环之前,我以此初始化一个新用户:

User user = FindUserPointer(setUser, id);

The function used is this: 使用的功能是这样的:

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;
}

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). Valgrind并不是在抱怨泄漏-它是在抱怨您正在读取未初始化的内存并取消引用无效的指针(无效的指针deref导致程序崩溃-至少在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). 我们需要查看UserGetID()UserGetName()才能确定其中的错误(但是可能还不够)。

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 . 根据您的评论mtmSuggestFriends是您没有源的目标文件,我猜测UsetGetID()和/或UserGetName()将无效的指针传递给mtmSuggestFriends

First, you are passing in an unassigned pointer user . 首先,您要传入一个未分配的指针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 ) 然后,从UserGetID()调用的SuggestFriends()函数将这个充满随机性的垃圾指针用作真实指针,从而导致无效读取( SEGV

You might find that setting "warnings as errors" ( -Werr on gcc) would probably show you where you are doing unpredictable things. 您可能会发现,设置“警告为错误”(gcc上的-Werr )可能会向您显示您在做不可预测的事情。

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

...and where is User defined ? ... User定义在哪里?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM