2012-05-04 74 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定義?