Semua fungsi yang disebutkan dalam blok ini adalah fungsi perpustakaan. Bagaimana saya bisa memperbaiki kebocoran memori ini?
Itu terdaftar di bawah kategori " Masih terjangkau ". (Ada 4 lebih, yang sangat mirip, tetapi dengan berbagai ukuran)
630 bytes in 1 blocks are still reachable in loss record 5 of 5
at 0x4004F1B: calloc (vg_replace_malloc.c:418)
by 0x931CD2: _dl_new_object (dl-object.c:52)
by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
by 0x92EFB6: _dl_map_object (dl-load.c:2251)
by 0x939F1B: dl_open_worker (dl-open.c:255)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0x9399C5: _dl_open (dl-open.c:584)
by 0xA64E31: do_dlopen (dl-libc.c:86)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)
Catch: Setelah saya menjalankan program saya, tidak ada kebocoran memori, tetapi ia memiliki satu baris tambahan dalam output Valgrind, yang sebelumnya tidak ada:
Membuang syms di 0x5296fa0-0x52af438 di /lib/libgcc_s-4.4.4-20100630.so.1 karena munmap ()
Jika kebocoran tidak dapat diperbaiki, bisakah seseorang setidaknya menjelaskan mengapa munmap () line menyebabkan Valgrind melaporkan 0 kebocoran yang "masih dapat dicapai"?
Edit:
Berikut ini contoh uji minimal:
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void *runner(void *param) {
/* some operations ... */
pthread_exit(NULL);
}
int n;
int main(void) {
int i;
pthread_t *threadIdArray;
n=10; /* for example */
threadIdArray = malloc((n+n-1)*sizeof(pthread_t));
for(i=0;i<(n+n-1);i++) {
if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
printf("Couldn't create thread %d\n",i);
exit(1);
}
}
for(i=0;i<(n+n-1);i++) {
pthread_join(threadIdArray[i],NULL);
}
free(threadIdArray);
return(0);
}
Jalankan dengan:
valgrind -v --leak-check=full --show-reachable=yes ./a.out
Jawaban:
Ada lebih dari satu cara untuk mendefinisikan "kebocoran memori". Secara khusus, ada dua definisi utama "kebocoran memori" yang umum digunakan di kalangan programmer.
Definisi "kebocoran memori" yang umum digunakan pertama adalah, "Memori dialokasikan dan tidak kemudian dibebaskan sebelum program dihentikan." Namun, banyak programmer (benar) berpendapat bahwa tipe tertentu dari kebocoran memori yang sesuai dengan definisi ini tidak benar-benar menimbulkan masalah, dan karenanya tidak boleh dianggap sebagai "kebocoran memori" yang sebenarnya.
Definisi yang lebih kuat (dan lebih bermanfaat) dari "kebocoran memori" adalah, "Memori dialokasikan dan tidak dapat kemudian dibebaskan karena program tidak lagi memiliki pointer ke blok memori yang dialokasikan." Dengan kata lain, Anda tidak dapat membebaskan memori yang tidak lagi memiliki petunjuk. Memori semacam itu karenanya merupakan "kebocoran memori". Valgrind menggunakan definisi yang lebih ketat tentang istilah "kebocoran memori". Ini adalah jenis kebocoran yang berpotensi menyebabkan penumpukan tumpukan yang signifikan, terutama untuk proses yang berumur panjang.
Kategori "masih dapat dijangkau" dalam laporan kebocoran Valgrind mengacu pada alokasi yang hanya sesuai dengan definisi pertama "kebocoran memori". Blok-blok ini tidak dibebaskan, tetapi mereka dapat dibebaskan (jika programmer ingin) karena program masih melacak pointer ke blok memori tersebut.
Secara umum, tidak perlu khawatir tentang blok "masih dapat dijangkau". Mereka tidak menimbulkan masalah yang bisa disebabkan oleh kebocoran memori yang sebenarnya . Misalnya, biasanya tidak ada potensi untuk tumpukan kehabisan dari blok "masih dapat dijangkau". Ini karena blok ini biasanya alokasi satu kali, referensi yang disimpan sepanjang durasi proses. Meskipun Anda dapat melewati dan memastikan bahwa program Anda membebaskan semua memori yang dialokasikan, biasanya tidak ada manfaat praktis dari melakukannya karena sistem operasi akan mendapatkan kembali semua memori proses setelah proses berakhir. Bandingkan ini dengan true kebocoran memori yang, jika dibiarkan tidak tetap, dapat menyebabkan proses kehabisan memori jika dibiarkan berjalan cukup lama, atau hanya akan menyebabkan proses untuk mengkonsumsi memori jauh lebih banyak daripada yang diperlukan.
Mungkin satu-satunya waktu yang berguna untuk memastikan bahwa semua alokasi memiliki pencocokan "membebaskan" adalah jika alat deteksi kebocoran Anda tidak dapat mengetahui blok mana yang "masih dapat dijangkau" (tetapi Valgrind dapat melakukan ini) atau jika sistem operasi Anda tidak mengklaim kembali semua memori proses terminating (semua platform yang telah diporting Valgrind untuk melakukan ini).
sumber
munmap
dipanggil sebagai akibat dari membongkar objek yang dibagikan. Dan semua sumber daya yang digunakan oleh objek yang dibagikan mungkin dibebaskan sebelum dibongkar. Ini bisa menjelaskan mengapa "masih terjangkau" dibebaskan dalammunmap
kasus ini. Saya hanya berspekulasi di sini. Tidak ada informasi yang cukup di sini untuk mengatakan dengan pasti.Karena ada beberapa rutin dari keluarga pthread di bagian bawah (tapi saya tidak tahu itu), tebakan saya adalah bahwa Anda telah meluncurkan beberapa utas sebagai joinable yang telah menghentikan eksekusi.
Informasi status keluar utas itu tetap tersedia sampai Anda menelepon
pthread_join
. Dengan demikian, memori disimpan dalam catatan kerugian pada saat penghentian program, tetapi masih dapat dijangkau karena Anda dapat menggunakannyapthread_join
untuk mengaksesnya.Jika analisis ini benar, luncurkan utas ini secara terpisah, atau bergabunglah sebelum menghentikan program Anda.
Sunting : Saya menjalankan program sampel Anda (setelah beberapa koreksi yang jelas) dan saya tidak memiliki kesalahan selain yang berikut
Karena
dl-
hal itu menyerupai banyak dari apa yang Anda lihat, saya kira Anda melihat masalah yang diketahui yang memiliki solusi dalam hal file penekanvalgrind
. Mungkin sistem Anda tidak mutakhir, atau distribusi Anda tidak mempertahankan hal-hal ini. (Milik saya adalah ubuntu 10.4, 64bit)sumber
Anda tampaknya tidak mengerti apa
still reachable
artinya.Apa pun
still reachable
itu bukan kebocoran. Anda tidak perlu melakukan apa-apa tentang itu.sumber
FILE
pointer hilang ?Berikut ini penjelasan yang tepat tentang "masih bisa dijangkau":
"Masih dapat dijangkau" adalah kebocoran yang ditetapkan untuk variabel global dan statis-lokal. Karena valgrind melacak variabel global dan statis, ia dapat mengecualikan alokasi memori yang ditetapkan "sekali-dan-lupakan". Variabel global menetapkan alokasi sekali dan tidak pernah ditugaskan kembali bahwa alokasi biasanya bukan "kebocoran" dalam arti bahwa itu tidak tumbuh tanpa batas. Ini masih merupakan kebocoran dalam arti yang ketat, tetapi biasanya dapat diabaikan kecuali jika Anda jago.
Variabel lokal yang diberi alokasi dan tidak bebas hampir selalu bocor.
Berikut ini sebuah contoh
Valgrind akan melaporkan working_buf sebagai "masih dapat dijangkau - 16k" dan temp_buf sebagai "pasti hilang - 5k".
sumber
Untuk pembaca masa depan, "Still Reachable" mungkin berarti Anda lupa menutup sesuatu seperti file. Meskipun tampaknya tidak seperti itu dalam pertanyaan awal, Anda harus selalu memastikan bahwa Anda telah melakukannya.
sumber