简体   繁体   中英

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. When I comment the code and run valgrind, I dont get any memory leak or error so this loop should be the cause:

///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:

==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?

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:

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

Here is the struct of the User and the getID and 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).

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 .

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.

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

...and where is User defined ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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