เป็นวิธีปฏิบัติที่ดีเสมอไปหรือไม่ที่จะตั้งค่าพอยน์เตอร์เป็น NULL หลังจาก free()-ing พวกมัน? [ทำซ้ำ]


person bodacydo    schedule 29.07.2010    source แหล่งที่มา
comment
@bodacydo ดูคำถามที่เกี่ยวข้องทางด้านขวาของหน้า   -  person    schedule 29.07.2010
comment
ขอบคุณนีลและไมเคิล คำถามนั้นตอบคำถามของฉันจริงๆ หลังจากอ่านคำตอบแล้ว ฉันมีคำถามอื่น - ไม่ได้ตั้งค่าตัวชี้เป็น NULL ซ่อนข้อผิดพลาดจริงหรือ ตรวจไม่พบ Double free() อีกต่อไป! ตอนนี้ฉันสับสนเพราะนี่เป็นการซ่อนข้อผิดพลาดไม่ให้ปรากฏขึ้นจริงๆ   -  person bodacydo    schedule 29.07.2010
comment
ยังไงล่ะ? การเพิ่มพอยน์เตอร์และตั้งค่าเป็น NULL จะทำให้หน่วยความจำว่าง หากคุณตัดสินใจที่จะปล่อยค่า NULL ฟรี คุณควรได้รับการยืนยันหรือคำเตือนอื่น ๆ การเพิ่มหน่วยความจำสองเท่านั้นยากต่อการติดตามมากกว่าการปล่อย NULL มาก   -  person Michael Dorgan    schedule 29.07.2010
comment
แต่การว่างสองเท่าในโปรแกรมของคุณแสดงว่าคุณเขียนโปรแกรมไม่ถูกต้อง การตั้งค่าตัวชี้เป็น NULL ซ่อนปัญหาและไม่ได้แก้ปัญหาจริงๆ   -  person bodacydo    schedule 29.07.2010
comment
หากคุณปล่อยว่าง NULL มันจะไม่ทำอะไรเลย คุณจะไม่ได้รับการยืนยัน นี่เป็นสิ่งที่ดีเพราะมันทำให้การล้างโค้ดง่ายขึ้น คุณต้องการ ifs น้อยลง แต่อย่างน้อยฉันก็สามารถเห็นได้ว่า OP มาจากไหนในมุมมองของการซ่อนข้อบกพร่อง   -  person zwol    schedule 29.07.2010
comment
@bodacydo: มันซ่อน double-frees แต่การไม่ทำเช่นนั้นอาจซ่อนข้อผิดพลาดของตัวชี้ไวด์ (การเข้าถึงตัวชี้หลังจากหน่วยความจำถูกปลดปล่อยแล้ว) เป็นการแลกเปลี่ยน ดังนั้นจึงไม่จำเป็นว่าแย่ (แต่ก็ไม่จำเป็นต้องดีเสมอไป) โดยส่วนตัวแล้วฉันไม่ถือว่าการไม่มีตัวชี้ว่างเพิ่มเติมจำเป็นต้องเป็นข้อบกพร่อง แต่การเข้าถึงตัวชี้แบบเสริมนั้น เสมอ ผิด ดังนั้นฉันจึงเข้าข้างด้วยการมอบหมายให้ NULL   -  person jamesdlin    schedule 29.07.2010
comment
ฉันเชื่อว่าตรรกะก็คือการฟรีสองเท่าเป็นข้อบกพร่องเล็ก ๆ ที่ใช้หน่วยความจำที่ได้รับการปลดปล่อยจริง ๆ สมมติว่าคุณอยู่บนเครื่องที่การยกเลิกการอ้างอิง NULL จะส่งสัญญาณให้คุณพบจุดบกพร่องที่สำคัญอย่างรวดเร็ว   -  person Darron    schedule 29.07.2010
comment
ฉันกำหนดตัวชี้ที่ตายแล้วให้กับ NULL เสมอเนื่องจากหน่วยความจำที่อยู่นั้นไม่ถูกต้องอีกต่อไป ฉันค่อนข้างชอบแนวคิดในการใช้ค่าการแทนที่ซึ่งตั้งค่าเป็น NULL ในโหมด release แต่บางอย่างเช่น (void*)0xdeadbeef ในโหมดแก้ไขข้อบกพร่อง เพื่อให้คุณสามารถตรวจจับการใช้งานที่ผิดพลาดได้   -  person Den-Jason    schedule 02.10.2019


คำตอบ (4)


การปฏิบัติที่ไม่ดีลงคะแนนจากฉัน หากคุณ ทำ ต้องการกำหนดค่า ให้ตั้งค่าเป็น (void*)0xdeadbeef ตรวจสอบสิ่งที่ CRT ของคุณสามารถทำได้ก่อน ตัวจัดสรรการดีบักที่เหมาะสมจะตั้งค่าหน่วยความจำที่ว่างเป็นรูปแบบที่มีแนวโน้มที่จะทำให้เกิดระเบิดเมื่อมีการใช้ตัวชี้หลังจากที่ปล่อยให้เป็นอิสระแล้ว ถึงแม้จะไม่รับประกันก็ตาม แต่การ ไม่ เปลี่ยนค่าตัวชี้จะเป็นวิธีแก้ปัญหาที่ดีกว่า (และเร็วกว่า)

person Hans Passant    schedule 29.07.2010

แม้ว่าจะไม่เจ็บ แต่ก็ไม่ได้ช่วยเสมอไป ปัญหาที่ต้องพิจารณาก็คือ มันง่ายที่จะมีสำเนาของตัวชี้หลายชุด และเป็นไปได้มากว่าคุณจะตั้งค่าตัวชี้เพียงชุดเดียวเป็น NULL ตัวอย่างคลาสสิกที่ไม่ช่วยอะไรเลยคือ:

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

ปัญหาที่นี่คือคุณกำลังตั้งค่าตัวชี้ที่อยู่ในเครื่องเป็น free_graph เป็น NULL เท่านั้นและตัวชี้ถูกยึดโดยผู้เรียก free_graph จะยังคงมีค่าดั้งเดิมอยู่

person R Samuel Klatchko    schedule 29.07.2010

นี่ถือเป็นแนวทางปฏิบัติที่ดีสำหรับบางคน เนื่องจากจะป้องกันไม่ให้คุณเข้าถึงหน่วยความจำโดยไม่ได้ตั้งใจหลังจากที่หน่วยความจำว่าง () แล้ว

person Darron    schedule 29.07.2010
comment
หลังจากอ่านคำตอบแล้ว ฉันพบว่ามันเป็นแนวทางปฏิบัติที่ไม่ดี - ฉันซ่อนข้อผิดพลาดของการปลอดสองเท่า! สิ่งนี้จะเป็นแนวทางปฏิบัติที่ดีได้อย่างไร? - person bodacydo; 29.07.2010
comment
จริงๆ แล้ว มันไม่ได้ป้องกันคุณโดยอัตโนมัติจากการเข้าถึงมัน แต่คุณสามารถ (และควร) ตรวจสอบกับตัวชี้ NULL เสมอ แต่คุณไม่สามารถบอกได้ว่าตัวชี้ที่ไม่ใช่ NULL นั้นถูกต้องหรือไม่ จึงเป็นการปฏิบัติที่ดี - person cypheon; 29.07.2010
comment
ฉันยังไม่มั่นใจว่ามันเป็นแนวทางปฏิบัติที่ดี - person bodacydo; 29.07.2010

ฉันคิดว่าใช่ ...

เมื่อคุณใช้ส่วนใดส่วนหนึ่งของ Menory เสร็จแล้ว เราควร free() มัน ซึ่งจะช่วยให้หน่วยความจำที่ว่างนั้นถูกใช้เพื่อวัตถุประสงค์อื่นบางอย่างได้...เช่น การเรียก malloc() เพิ่มเติม

Free นำตัวชี้ไปที่หน่วยความจำเป็นอาร์กิวเมนต์ และเพิ่มหน่วยความจำที่ตัวชี้อ้างถึง...

หวังว่านี่จะช่วยได้ ... :)

person Flash    schedule 29.07.2010
comment
-1: สิ่งนี้ไม่ตอบคำถาม bodacydo ไม่ได้ถาม เขาควรจะเพิ่มหน่วยความจำหรือไม่ เขาถามว่าควรตั้งค่าพอยน์เตอร์เป็น NULL หรือไม่หลังจากปล่อยมันแล้ว - person Platinum Azure; 29.07.2010