2012-05-04 13 views
1

valgrindでエラーを生成するコードのこの小さな部分に問題があります。この小さなforループのメモリリークと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の実行すると、私はこのループが原因である必要がありますので、任意のメモリリークやエラーを取得いけません。

ここでエラーが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 

のconst char型のmalloc関数* ..だから私は右のそれを解放することを心配はずのを返すToStringUser機能?

なぜこのようなことが起こっているのですか?

私はのために、このコードでSTRを解放しようとしたが、私は同じエラーやメモリリークの同じ量を得続ける:ここ

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

は、ユーザーとのgetIdとのgetNameの構造体であります

User user = FindUserPointer(setUser, id); 

:私はこれで新しいユーザーを初期化ループの前に

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

使用する関数はこれです:

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'関数でsegfaultsするので、それを見ると便利かもしれません。 – huon

答えて

4

Valgrindのは、リーク文句を言っていない - あなたが初期化されていないメモリを読み取り、無効なポインタを逆参照していることを訴えています(無効なポインタDEREFは、プログラムをクラッシュされる - 少なくともValgrindの下) 。

UserGetID()UserGetName()を参照して、これらのバグを判断することができます(それでもまだ不十分かもしれません)。

mtmSuggestFriendsあなたがソースを持っていないオブジェクトファイルであることをあなたのコメントに基づいて、私の推測では、UsetGetID()および/またはUserGetName()mtmSuggestFriendsに無効なポインタを渡しているということです。

+0

コードが更新されました。 mtmSuggestFriendsはオブジェクトファイル内の関数です。 mallocしてconst char *を返します。それは私の友人の多くがそれを使用し、それを使用するときに0リークを持っているので、その漏れの原因ではありません。 – Omar

+0

forループをアサートで更新しました(上記のコードを参照)。 – Omar

+0

これ以上のことは分かっていますが、 'FindUserPointer()'に渡されたデータがどのようなものか、 'SET_FOREACH()'のデータが何であるか分かりません。しかし、あなたの 'mtmSuggestFriends'の記述に基づいて、ヒープが壊れている可能性があります。たぶん 'UserCreate()'にバグがあります( 'Name'文字列にヌルターミネーターを含めるのに十分なメモリを割り当てられていないかもしれません)。 –

0

最初に、割り当てられていないポインタuserを渡しています。その後UserGetID()から呼び出され、あなたのSuggestFriends()機能が無効な読み取りにつながる本当のポインタとしてランダム性の完全な、このゴミのポインタを使用している(SEGV

あなたはおそらく表示されるでしょう(GCCの-Werr)「エラーとして警告」を設定することがありますあなたが予測できないことをしている場所。

+0

私は割り当てたユーザーでコードを更新しました。私はeclipseでコードをデバブしました。このエラーになると、ユーザはNULLではありません。 – Omar

+0

正確には、NULLではありません。有効なポインタではない値です。おそらく、valgrindが初期化されていない変数の使用について不平を言います。ポインタをNULLに初期化する必要があります。 – IanNorton

+0

私はこれを試しました:\tユーザユーザ= 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はどこですか?