2012-05-04 44 views
1

我在使用valgrind生成错误的这一小部分代码遇到问题。当我评论的代码和运行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 * ..所以我不应该担心释放它右边的功能?

任何想法为什么会发生这种情况?

我试图将此代码为解救海峡,但我不断收到同样的错误和相同数量的内存泄漏:

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

这里是用户的结构和的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; 
} 
+0

为什么你不担心释放它? – msam

+5

你应该总是担心释放内存。 – Philip

+1

for循环中的'user'是什么?程序在'mtmSuggestFriends'函数中进行段错误,因此可能会有用。 – huon

回答

4

Valgrind是不是抱怨泄漏 - 它的抱怨,你读未初始化的内存和访问一个空指针(无效指针DEREF崩溃的程序 - 至少在Valgrind的) 。

我们就需要看UserGetID()UserGetName()有确定这些错误的希望(但仍可能不够)。

基于您的评论是mtmSuggestFriends是,你没有来源的对象文件,我的猜测是,UsetGetID()和/或UserGetName()被传递无效指针mtmSuggestFriends

+0

用代码更新的问题。 mtmSuggestFriends是一个对象文件中的函数。它mallocs并返回一个const char *。它不是我的许多朋友使用它的泄漏原因,并且在使用时泄漏量为0。 – Omar

+0

我用断言更新了for循环(见上面的代码),它仍然在工作。 – Omar

+0

现在我们知道更多,但不知道传递给FindUserPointer()的数据看起来像什么或者SET_FOREACH()是什么。但是根据你对mtmSuggestFriends的描述,问题可能是堆已损坏。也许'UserCreate()'有一个错误(可能没有分配足够的内存来在'Name'字符串中包含null终止符?)。 –

0

首先,您传入未分配的指针user。然后你SuggestFriends()功能从UserGetID()称为使用这种垃圾指针充满了随意性作为一个真正的指针导致无效读(SEGV

你可能会发现,设置“警告视为错误”(-Werr海合会)可能会显示你在哪里做不可预知的事情。

+0

我更新了用户分配的代码。我用eclipse debbuilder代码,并且在达到这个错误时用户不是NULL。 – Omar

+0

确切地说,它不是NULL,它是一个不是有效指针的值,可能来自valgrind抱怨使用未初始化变量的地方。您应该始终将指针初始化为NULL。 – IanNorton

+0

我试过这个:\t User user = NULL; \t user = FindUserPointer(setUser,id); 这是你的意思吗?我仍然得到相同的错误。我也尝试在FindUserPointer中返回用户的COPY,但仍然是smae。 – Omar

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

...以及其中User定义?