Apakah selalu merupakan praktik yang baik untuk menyetel pointer ke NULL setelah membebaskannya ()? [duplikat]

Kemungkinan Duplikat:
Mengatur variabel ke NULL setelah gratis

Saya belajar tentang praktik pemrograman C yang baik dan teman saya mengatakan kepada saya untuk selalu mengatur pointer ke NULL setelah membebaskannya (atau memanggil fungsi pembebasan tertentu).

Misalnya:

char* ptr = malloc(100);
...
free(ptr);
ptr = NULL;

or

struct graph* graph = create_graph();
...
destroy_graph(graph);
graph = NULL;

Mengapa ini merupakan praktik yang baik?

Pembaruan: Setelah membaca jawabannya, menurut saya ini merupakan praktik yang buruk! Saya menyembunyikan kemungkinan kesalahan double-free(). Bagaimana ini bisa menjadi praktik yang baik? Aku kaget.

Terima kasih, Boda Cydo.


person bodacydo    schedule 29.07.2010    source sumber
comment
@bodacydo Lihatlah pertanyaan terkait di sebelah kanan halaman.   -  person    schedule 29.07.2010
comment
Terima kasih Neil dan Michael. Pertanyaan itu benar-benar menjawab pertanyaan saya. Setelah membaca jawaban saya punya pertanyaan lain - bukankah pengaturan pointer ke NULL sebenarnya menyembunyikan kesalahan? Double free() tidak lagi terdeteksi! Saya sekarang bingung karena ini benar-benar menyembunyikan kesalahan agar tidak muncul.   -  person bodacydo    schedule 29.07.2010
comment
Bagaimana? Membebaskan pointer dan mengaturnya ke NULL memungkinkan memori dibebaskan. Jika Anda kemudian memutuskan untuk membebaskan NULL, Anda akan mendapatkan pernyataan atau peringatan lainnya. Membebaskan memori secara ganda jauh lebih sulit dilacak daripada membebaskan NULL.   -  person Michael Dorgan    schedule 29.07.2010
comment
Namun tanda bebas ganda di program Anda menunjukkan bahwa Anda telah menulis program yang salah. Menyetel penunjuk ke NULL menyembunyikan masalah dan tidak benar-benar menyelesaikannya.   -  person bodacydo    schedule 29.07.2010
comment
Jika Anda membebaskan NULL, secara diam-diam tidak melakukan apa pun, Anda tidak mendapatkan pernyataan. Ini adalah Hal yang Baik karena membuat pembersihan kode lebih mudah, Anda memerlukan lebih sedikit jika; tapi setidaknya saya bisa melihat dari mana OP itu berasal dari perspektif menyembunyikan bug.   -  person zwol    schedule 29.07.2010
comment
@bodacydo: Ini menyembunyikan pembebasan ganda, tetapi tidak melakukannya berpotensi menyembunyikan kesalahan penunjuk liar (mengakses penunjuk setelah memori dibebaskan). Ini trade-off, jadi tidak harus buruk (tapi belum tentu baik). Secara pribadi saya tidak menganggap tambahan pointer nol gratis sebagai bug, tetapi mengakses pointer liar selalu salah, jadi saya memilih menugaskan ke NULL.   -  person jamesdlin    schedule 29.07.2010
comment
Saya percaya logikanya adalah double free adalah bug kecil yang sebenarnya menggunakan memori yang telah dibebaskan. Dengan asumsi bahwa Anda berada pada mesin di mana dereferensi NULL menimbulkan sinyal, Anda dengan cepat menemukan bug kritis.   -  person Darron    schedule 29.07.2010
comment
Saya selalu menetapkan pointer mati ke NULL karena memori alamatnya tidak lagi valid. Saya cukup menyukai gagasan menggunakan nilai ganti yang disetel ke NULL dalam mode rilis, tetapi sesuatu seperti (void*)0xdeadbeef dalam mode debug sehingga Anda dapat mendeteksi penggunaan yang salah.   -  person Den-Jason    schedule 02.10.2019


Jawaban (4)


Suara praktik buruk dari saya. Jika Anda ingin memberikan nilai, setel ke (void*)0xdeadbeef. Periksa terlebih dahulu apa yang dapat dilakukan CRT Anda. Pengalokasi debug yang layak akan mengatur memori yang dibebaskan ke pola yang mungkin menyebabkan bom ketika penunjuk digunakan setelah dibebaskan. Meskipun hal itu tidak dijamin. Namun tidak mengubah nilai penunjuk adalah solusi yang lebih baik (dan lebih cepat).

person Hans Passant    schedule 29.07.2010

Meskipun tidak ada salahnya, namun tidak selalu membantu. Masalah yang perlu dipertimbangkan adalah mudahnya terdapat banyak salinan penunjuk dan kemungkinan besar Anda hanya akan menyetel satu salinan ke NULL. Contoh klasik yang tidak membantu sama sekali adalah:

void free_graph(graph *g)
{
    ...
    free(g);
    g = NULL;  // not useful in this context
}

Masalahnya di sini adalah Anda hanya menyetel pointer lokal ke free_graph ke NULL dan pointer yang dipegang oleh pemanggil free_graph akan tetap memiliki nilai aslinya.

person R Samuel Klatchko    schedule 29.07.2010

Hal ini dianggap sebagai praktik yang baik oleh beberapa orang karena mencegah Anda mengakses memori secara tidak sengaja setelah memori tersebut di-free().

person Darron    schedule 29.07.2010
comment
Setelah membaca jawabannya, saya menemukan ini adalah praktik yang buruk - saya menyembunyikan kesalahan bebas ganda! Bagaimana ini bisa menjadi praktik yang baik? - person bodacydo; 29.07.2010
comment
Sebenarnya, ini tidak secara otomatis mencegah Anda mengaksesnya, tetapi Anda dapat (dan harus) selalu memeriksa pointer NULL, tetapi Anda tidak dapat mengetahui apakah pointer bukan-NULL itu valid. Oleh karena itu, ini adalah praktik yang baik. - person cypheon; 29.07.2010
comment
Saya belum yakin bahwa ini adalah praktik yang baik. - person bodacydo; 29.07.2010

Saya pikir ya ...

Ketika Anda telah selesai menggunakan sebagian menory , kita harus free() itu. Hal ini memungkinkan memori yang dibebaskan untuk digunakan untuk beberapa tujuan lain...seperti panggilan malloc() lebih lanjut.

Free mengambil pointer ke memori sebagai argumen dan membebaskan memori yang dirujuk oleh pointer...

Semoga ini membantu ... :)

person Flash    schedule 29.07.2010
comment
-1: Ini tidak menjawab pertanyaan. bodacydo tidak bertanya, haruskah dia membebaskan ingatannya. Dia bertanya, haruskah dia menyetel pointer ke NULL setelah membebaskannya. - person Platinum Azure; 29.07.2010