ใน C ++ เวลาโปรแกรมเมอร์ที่ใช้ในการจัดการหน่วยความจำ


39

คนที่เคยชินกับภาษาที่รวบรวมขยะมักจะกลัวการจัดการหน่วยความจำของ C ++ มีเครื่องมือเช่นauto_ptrและshared_ptrที่จะจัดการงานการจัดการหน่วยความจำมากมายสำหรับคุณ ไลบรารี C ++ จำนวนมากลงวันที่ก่อนวันจริงเครื่องมือเหล่านี้และมีวิธีของตัวเองในการจัดการงานการจัดการหน่วยความจำ

คุณใช้เวลากับงานการจัดการหน่วยความจำนานเท่าใด

ฉันสงสัยว่ามันขึ้นอยู่กับชุดของห้องสมุดที่คุณใช้อย่างมากดังนั้นโปรดบอกว่าคำตอบที่คุณใช้กับคนใดและถ้าพวกเขาทำให้ดีขึ้นหรือแย่ลง


1
ไม่มากจริง ๆ ... โดยเฉพาะอย่างยิ่งกับ C ++ 0x การอ้างอิงและ STL คุณสามารถเขียนโค้ดโดยไม่มีการจัดการหน่วยความจำเลย
Coder

9
โดยทั่วไป: ไม่มากถ้าคุณมีประสบการณ์ มีมากถ้าคุณเป็นสามเณรถึง C ++ (-> มักตามล่าการรั่วไหลของหน่วยความจำ / ทรัพยากร)
MaR

1
ฉันพบคำถามจริงวันนี้มีมากขึ้นเกี่ยวกับการไล่อ้างอิงที่ค้าง และมักจะเห็นได้ชัดในแต่ละครั้งเพียงแค่น่ารำคาญที่ไม่เคยมีใครจับมาก่อน: p
Matthieu M.

ฉันรู้ว่ามันเก่า แต่การจัดการหน่วยความจำ IMO เป็นส่วนสำคัญของการเป็นโปรแกรมเมอร์ที่ดี Abstractions เช่นคอนเทนเนอร์ STL นั้นดี แต่การไม่จดจำหน่วยความจำขัดต่อแนวคิดในการคำนวณ หนึ่งอาจถามว่าจะสามารถกำจัดการจัดการพีชคณิต, ตรรกะและการวนซ้ำจากคลังแสงของโปรแกรมเมอร์
imallett

วิธี "ใช้เวลานานเท่าใดในการดีบักการจัดการหน่วยความจำผิดพลาด" การจัดการหน่วยความจำเป็นไปได้และไม่ยากใน C ++ ความจริงคือ: การตั้งค่าเป็นงานฝีมือที่แม่นยำและมีแนวโน้มที่จะมีเพศสัมพันธ์มาก เมื่อคุณมีเพศสัมพันธ์คุณอาจไม่ได้สังเกตเห็นและติดตามกลับไปสู่ข้อผิดพลาดเก่าที่มีพฤติกรรมผิดปกติที่เกิดขึ้นในช่วงเวลานั้นเป็นเวลาจริงที่คุณควรกลัว นั่นเป็นสาเหตุที่ภาษาที่ไม่ได้รวบรวมขยะสมัยใหม่ (ฉันกำลังคิดสนิม) ได้รับผิดชอบอย่างมากในการตรวจสอบข้อผิดพลาดทั่วไปไปยังคอมไพเลอร์
ZJR

คำตอบ:


54

C ++ ที่ทันสมัยทำให้คุณไม่ต้องกังวลเกี่ยวกับการจัดการหน่วยความจำจนกว่าคุณจะต้องทำนั่นคือจนกว่าคุณจะต้องจัดระเบียบหน่วยความจำด้วยมือส่วนใหญ่เพื่อการเพิ่มประสิทธิภาพหรือถ้าบริบทบังคับให้คุณทำ (คิดว่าฮาร์ดแวร์มีข้อ จำกัด ขนาดใหญ่) ฉันเขียนเกมทั้งหมดโดยไม่ต้องจัดการกับหน่วยความจำแบบดิบเพียงแค่กังวลเกี่ยวกับการใช้คอนเทนเนอร์ที่เป็นเครื่องมือที่เหมาะสมสำหรับงานเช่นในภาษาใด ๆ

ดังนั้นจึงขึ้นอยู่กับโครงการ แต่ส่วนใหญ่ไม่ใช่การจัดการหน่วยความจำที่คุณต้องจัดการ แต่ใช้เวลาวัตถุเท่านั้น ที่มีการแก้ไขได้โดยใช้ตัวชี้สมาร์ทที่เป็นหนึ่งในสำนวนภาษา C ++ เครื่องมือที่เกิดจากการRAII

เมื่อคุณเข้าใจRAIIการจัดการหน่วยความจำจะไม่เป็นปัญหา

จากนั้นเมื่อคุณจะต้องเข้าถึงหน่วยความจำแบบดิบคุณจะต้องทำในรหัสเฉพาะที่แปลเป็นภาษาท้องถิ่นและสามารถระบุตัวตนได้เช่นในการใช้งานออบเจ็กต์พูลไม่ใช่ "ทุกที่"

นอกเหนือจากรหัสประเภทนี้คุณไม่จำเป็นต้องจัดการหน่วยความจำเพียงอายุการใช้งานวัตถุ

ส่วน "ยาก" คือการเข้าใจ RAII


10
จริงที่สุด. ในช่วง 5 ปีที่ผ่านมาฉันเพิ่งเขียน "ลบ" เมื่อทำงานกับรหัสดั้งเดิมเท่านั้น
drxzcl

3
ฉันทำงานในสภาพแวดล้อมแบบฝังตัวที่มีข้อ จำกัด สูงมาก เท่อย่างที่ RAII ใช้งานได้ไม่ดีถ้าพื้นที่สแต็คมีค่าสูง ดังนั้นมันจึงกลับไปที่การจัดการไมโครพอยน์เตอร์
bastibe

1
@nikie ฉันใช้ตัวชี้สมาร์ทไลบรารีในรหัสที่จัดการ API ของพวกเขาจากนั้นฉันจะใช้ตัวชี้มาตรฐานหรือเพิ่มตัวชี้อัจฉริยะในรหัสเฉพาะสำหรับแอปพลิเคชันของฉัน (ถ้าฉันเป็นผู้ตัดสินใจเรื่องนั้น) หากคุณสามารถแยกรหัสห้องสมุดในบางโมดูลที่เป็นนามธรรมว่ามีการใช้งานอย่างไรในแอปพลิเคชันของคุณคุณจะหลีกเลี่ยงการเกิดมลพิษ API จากการพึ่งพา
Klaim

12
@Paperflyer: RAII จะไม่ใช้พื้นที่สแต็กมากกว่าdeleteด้วยตนเองเว้นแต่คุณจะมีการใช้งานที่ไม่เหมาะสม
DeadMG

2
@Paperflyer: ตัวชี้สมาร์ทบนฮีปใช้พื้นที่เดียวกัน ความแตกต่างคือคอมไพเลอร์แทรกรหัสการจัดสรรทรัพยากรในการออกทั้งหมดจากฟังก์ชั่น และเนื่องจากมีการใช้กันอย่างแพร่หลายดังนั้นจึงเป็นวิธีที่ได้รับการปรับให้เหมาะสมที่สุด (เช่นการพับการออกหลายทางด้วยกันในแบบที่คุณทำไม่ได้ - คุณไม่สามารถใส่รหัสหลังได้return)
MSalters

32

การจัดการหน่วยความจำใช้เพื่อทำให้เด็ก ๆ หวาดกลัว แต่เป็นทรัพยากรประเภทเดียวที่โปรแกรมเมอร์ต้องดูแล คิดถึงการจัดการไฟล์การเชื่อมต่อเครือข่ายทรัพยากรอื่น ๆ ที่คุณได้รับจากระบบปฏิบัติการ

ภาษาที่รองรับการรวบรวมขยะมักจะไม่เพียง แต่เพิกเฉยต่อการมีอยู่ของทรัพยากรเหล่านี้ แต่พวกเขายังทำให้ยากที่จะจัดการกับสิ่งเหล่านี้อย่างถูกต้องโดยไม่ให้ตัวทำลาย

ดังนั้นในระยะสั้นฉันขอแนะนำไม่ได้ว่าเวลาส่วนใหญ่ของนักพัฒนา C ++ นั้นใช้เวลากังวลเกี่ยวกับการจัดการหน่วยความจำ เมื่อคำตอบของ klaimบ่งบอกว่าเมื่อคุณได้รับการจัดการจาก RAII ส่วนที่เหลือก็เป็นเพียงการสะท้อนกลับ


3
ฉันชอบที่ HttpWebRequest.GetResponse รั่วไหลและจัดการกับภาษา GC เป็นพิเศษ GC เย็นจนเริ่มดูดเนื่องจากทรัพยากรยังคงรั่วไหล msdn.microsoft.com/en-us/library/…โปรดดู "ข้อควรระวัง"
Coder

6
+1 สำหรับการดูหน่วยความจำเป็นทรัพยากร รหัสเดิมหรือไม่กี่ครั้งที่เราจะต้องตะโกนออกมาดัง ๆ : การบริหารจัดการหน่วยความจำเป็นทักษะและไม่ได้เป็นคำสาปแช่ง
aquaherd

4
@Coder ไม่แน่ใจว่าฉันติดตาม .. GC ดูดเพราะเป็นไปได้ที่จะใช้ทรัพยากรในทางที่ผิดหรือไม่ .. ? ฉันคิดว่า C # ทำงานได้ดีในการปล่อยทรัพยากรที่กำหนดขึ้นโดยใช้ IDisposable ...
สูงสุด

8
@ Max: เพราะหากมีการเก็บขยะฉันคาดหวังว่าจะไม่ต้องกังวลเกี่ยวกับทรัพยากรที่โง่ผ่านการใช้และ IDisposables ที่กำหนดเอง ทรัพยากรออกจากขอบเขตนั่นก็คือพวกเขาควรได้รับการทำความสะอาด ในความเป็นจริงฉันยังต้องคิดและเดาว่าอันไหนจะรั่วและอันไหนจะไม่ เอาชนะทุก ๆ เหตุผลในการใช้ภาษา GC ตั้งแต่แรก
Coder

5
@deadalnix พวกเขามีfinalizeโครงสร้าง อย่างไรก็ตามคุณไม่ทราบว่าจะมีการเรียกเมื่อใด มันจะเป็นก่อนที่คุณจะหมดซ็อกเก็ตหรือวัตถุ WebResponse? คุณจะพบบทความมากมายที่บอกคุณว่าคุณไม่ควรพึ่งพาfinalize- ด้วยเหตุผลที่ดี
Dysaster

13

ค่อนข้างไม่มีเลย แม้แต่เทคโนโลยีเก่า ๆ เช่น COM คุณสามารถเขียนนักกำหนดเองสำหรับตัวชี้มาตรฐานที่จะแปลงพวกเขาในเวลาอันสั้น ตัวอย่างเช่นstd::unique_ptrสามารถแปลงให้มีการอ้างอิง COM โดยไม่ซ้ำกับห้าบรรทัดของ deleter ที่กำหนดเอง แม้ว่าคุณจะต้องเขียนตัวจัดการทรัพยากรของคุณด้วยตนเองความชุกของความรู้เช่น SRP และการคัดลอกและสลับจะทำให้การเขียนคลาสการจัดการทรัพยากรใช้งานได้ง่ายขึ้น

ความจริงก็คือการใช้งานร่วมกันไม่เหมือนใครและไม่ได้เป็นเจ้าของทั้งหมดมาพร้อมกับคอมไพเลอร์ C ++ 11 ของคุณและคุณต้องเขียนอะแดปเตอร์ขนาดเล็กเพื่อให้สามารถใช้งานได้แม้จะใช้รหัสเก่า


1
คุณต้องใช้ทักษะ C ++ มากแค่ไหนในการ a) เขียนตัวลบแบบกำหนดเอง b) รู้ว่าตัวกำหนดแบบกำหนดเองคือสิ่งที่คุณต้องการ? ฉันถามเพราะดูเหมือนว่าจะง่ายต่อการเลือกภาษา GC'd ใหม่และได้ใกล้เคียงกับการแก้ไขโดยไม่ทราบว่าทั้งหมด - มันเป็นเรื่องง่ายที่จะได้รับสิทธิใน C ++ เช่นกัน?
Sean McMillan

1
@SeanMcMillan: deleters ที่กำหนดเองมีความสำคัญต่อการเขียนและการปรับใช้ COM หนึ่งที่ฉันกล่าวถึงคือห้าบรรทัดสำหรับ COM ทุกประเภทและทุกคนที่มีการฝึกอบรมขั้นพื้นฐานใน C ++ ที่ทันสมัยควรคุ้นเคยกับพวกเขา คุณไม่สามารถเลือกภาษา GCed ได้เนื่องจากความประหลาดใจ GC จะไม่รวบรวมวัตถุ COM หรือจัดการไฟล์ หรือหน่วยความจำที่ได้จากระบบอื่น หรือการเชื่อมต่อฐานข้อมูล RAII จะทำสิ่งเหล่านั้นทั้งหมด
DeadMG

2
โดย "เลือกภาษา GC'd" ฉันหมายความว่าฉันกระโดดระหว่าง Java / C # / Ruby / Perl / Javascript / Python และพวกเขาทั้งหมดมีรูปแบบการจัดการทรัพยากรที่เหมือนกัน - หน่วยความจำส่วนใหญ่เป็นอัตโนมัติและทุกอย่างอื่น คุณต้องจัดการ ฟังดูเหมือนว่าฉันกำลังบอกว่าเครื่องมือการจัดการของ C ++ ช่วยให้คุณจัดการการจัดการไฟล์ / การเชื่อมต่อฐานข้อมูล / ฯลฯ ในลักษณะเดียวกับหน่วยความจำและมันค่อนข้างตรงไปตรงมาเมื่อคุณเรียนรู้ ไม่ต้องผ่าตัดสมอง ฉันเข้าใจถูกต้องหรือไม่
Sean McMillan

3
@SeanMcMillan: ใช่ถูกต้องและไม่ซับซ้อน
DeadMG

11

เมื่อฉันเป็น C ++ Programmer (นานมาแล้ว) ผมใช้เวลากังวลเวลานานเกี่ยวกับข้อบกพร่องการจัดการหน่วยความจำเมื่อพยายามที่จะแก้ไขยากที่จะทำซ้ำข้อบกพร่อง

ด้วยโมเด็ม C ++ การจัดการหน่วยความจำมีปัญหาน้อยกว่ามาก แต่คุณสามารถไว้วางใจทุกคนในทีมขนาดใหญ่เพื่อทำให้ถูกต้อง ราคา / เวลาของ:

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

ดังนั้นไม่ใช่แค่เวลาที่ใช้ " ทำ " นี่เป็นปัญหาของโครงการขนาดใหญ่


2
ฉันคิดว่าโปรเจ็กต์ C ++ บางโครงการหมดหวังที่จะแก้ไขการรั่วไหลของหน่วยความจำบางส่วนเนื่องจากโค้ดที่เขียนไม่ดี รหัสที่ไม่ถูกต้องจะเกิดขึ้นและเมื่อใดที่ต้องใช้เวลามากเช่นกัน
Jeremy

@ Jeremy ฉันพบว่าเมื่อฉันย้ายจาก C ++ เป็น C # ยังคงมีรหัสที่เขียนไม่ดีมาก (ถ้าไม่มาก) แต่อย่างน้อยมันก็ง่ายมากที่จะหาส่วนของโปรแกรมที่มีจุดบกพร่องที่กำหนด
เอียน

1
ใช่นี่คือสาเหตุที่ร้านค้าส่วนใหญ่ย้ายไปที่ Java หรือ. NET การรวบรวมขยะช่วยลดความเสียหายที่ไม่อาจหลีกเลี่ยงได้ของรหัสที่ไม่ถูกต้อง
Jeremy

1
ผิดปกติพอเราไม่มีปัญหาเหล่านั้น
David Thornley

1
@ DavidThornley ฉันคิดว่าปัญหามากมายมาจากการเขียนรหัส UI ใน C ++ ทุกวันนี้รหัส C ++ ส่วนใหญ่ที่ฉันเห็นไม่ใช่ UI
Ian

2

ฉันใช้เพิ่มและไลบรารี TR1 มากและพวกเขาทำให้การจัดการหน่วยความจำอย่างเข้มงวด (ใหม่ / ลบ) ไม่ใช่ปัญหา ในอีกทางหนึ่งการจัดสรรหน่วยความจำใน C ++ นั้นไม่ถูกและใคร ๆ ก็ต้องใส่ใจว่าตัวชี้ที่ใช้ร่วมกันเหล่านี้ถูกสร้างขึ้นอย่างไร คุณใช้พื้นที่ทำงานมากหรือทำงานกับหน่วยความจำแบบสแต็ก โดยทั่วไปฉันจะบอกว่าส่วนใหญ่เป็นปัญหาการออกแบบไม่ใช่ปัญหาการใช้งาน


2

ใช้เวลาเท่าไหร่ในฐานะลูกค้า? น้อยมากเมื่อคุณได้รับมัน เมื่อคอนเทนเนอร์จัดการอายุการใช้งานและการอ้างอิงมันเป็นเรื่องง่ายมาก เช่นนั้นง่ายกว่าการนับการอ้างอิงด้วยตนเองและมีความโปร่งใสในทางปฏิบัติหากคุณพิจารณาคอนเทนเนอร์ที่คุณใช้เป็นเอกสารซึ่งคอมไพเลอร์ป้องกันไม่ให้คุณทำการโอนกรรมสิทธิ์ที่ไม่ถูกต้องในระบบ typesafe ที่ออกแบบมาอย่างดี

เวลาส่วนใหญ่ที่ฉันใช้จ่าย (ในฐานะลูกค้า) นั้นมีประเภทจาก apis อื่นดังนั้นจึงทำงานได้ดีในบริบทของโปรแกรมของคุณ ตัวอย่างเช่นนี้เป็นภาชนะ ThirdPartyFont ของฉันและมันสนับสนุนคุณลักษณะเหล่านี้และดำเนินการทำลายด้วยวิธีนี้และการอ้างอิงนับด้วยวิธีนี้และการคัดลอกวิธีนี้และ ... หลายสิ่งก่อสร้างเหล่านี้จำเป็นต้องอยู่ในสถานที่และมักจะเป็นสถานที่ที่มีเหตุผลที่จะนำพวกเขาไป ไม่ว่าคุณต้องการที่จะรวมที่เป็นเวลาหรือไม่ขึ้นอยู่กับคำจำกัดความของคุณ (การดำเนินการจะต้องมีอยู่เมื่อเชื่อมต่อกับ API เหล่านี้ใช่ไหม?)

หลังจากนั้นคุณจะต้องคำนึงถึงความจำและความเป็นเจ้าของ ในระบบระดับล่างนั้นดีและจำเป็น แต่อาจต้องใช้เวลาและการนั่งร้านเพื่อใช้วิธีที่คุณควรเคลื่อนย้ายสิ่งต่าง ๆ ฉันไม่เห็นว่ามันเป็นความเจ็บปวดเพราะนี่เป็นข้อกำหนดของระบบระดับล่าง ความเป็นเจ้าของการควบคุมและความรับผิดชอบมีความชัดเจน

เพื่อให้เราสามารถเปลี่ยนไปสู่ ​​apis ที่ใช้ประเภท opaque: คอนเทนเนอร์ของเราอนุญาตให้เราสรุปรายละเอียดการใช้งานเล็กน้อยของการจัดการอายุการใช้งานและการคัดลอกประเภท opaque เหล่านั้นซึ่งท้ายที่สุดทำให้การจัดการทรัพยากรง่ายมากและประหยัดเวลาข้อบกพร่อง และลดการใช้งาน

มันง่ายมากที่จะใช้สิ่งเหล่านี้ - ปัญหา (มาจาก GC) คือตอนนี้คุณต้องพิจารณาอายุการใช้งานทรัพยากรของคุณ หากคุณเข้าใจผิดอาจใช้เวลานานในการแก้ไข การเรียนรู้และบูรณาการการจัดการตลอดชีวิตอย่างชัดเจนนั้นมีความซับซ้อนในการเปรียบเทียบ (ไม่ใช่สำหรับทุกคน) - นั่นเป็นอุปสรรค์ที่แท้จริง เมื่อคุณสะดวกสบายในการควบคุมอายุการใช้งานและการใช้โซลูชันที่ดีแล้วมันเป็นเรื่องง่ายมากที่จะจัดการอายุการใช้งานทรัพยากร มันไม่ได้เป็นส่วนสำคัญของวันของฉัน (ยกเว้นข้อผิดพลาดที่ยากพุ่งเข้ามา)

หากคุณไม่ได้ใช้ตู้คอนเทนเนอร์ (ตัวชี้ auto / shared) แสดงว่าคุณแค่ขอร้องให้เจ็บปวด

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


1

คุณหมายถึงต้องการที่จะเพิ่มหน่วยความจำด้วยตนเอง, ปิดไฟล์, สิ่งของประเภทนี้? ถ้าเป็นเช่นนั้นฉันจะบอกว่าขั้นต่ำและโดยทั่วไปแล้วจะน้อยกว่าภาษาอื่น ๆ ส่วนใหญ่ที่ฉันเคยใช้โดยเฉพาะอย่างยิ่งถ้าเราพูดคุยทั่วไปว่าไม่ใช่แค่ "การจัดการหน่วยความจำ" แต่ "การจัดการทรัพยากร" ในแง่นั้นฉันคิดว่า C ++ ต้องการการจัดการทรัพยากรด้วยตนเองน้อยกว่าพูด Java หรือ C #

สาเหตุหลักมาจาก destructors ที่ทำลายทรัพยากรโดยอัตโนมัติ (หน่วยความจำหรืออย่างอื่น) โดยทั่วไปครั้งเดียวที่ฉันต้องฟรี / ทำลายทรัพยากรด้วยตนเองใน C ++ คือถ้าฉันใช้โครงสร้างข้อมูลระดับต่ำ (สิ่งที่คนส่วนใหญ่ไม่จำเป็นต้องทำ) หรือใช้ C API ที่ฉันใช้เวลาเพียงเล็กน้อย การรวมรีซอร์ส C ที่ต้องอิสระ / ทำลาย / ปิดด้วยตนเองลงใน wrapper C ++ ที่สอดคล้องกับ RAII

แน่นอนว่าหากผู้ใช้ต้องการปิดภาพในซอฟต์แวร์แก้ไขภาพฉันต้องลบภาพออกจากคอลเลกชันหรือบางสิ่งบางอย่าง แต่หวังว่าจะไม่นับเป็นการจัดการ "หน่วยความจำ" หรือ "ทรัพยากร" ของสิ่งที่มีความสำคัญในบริบทนี้เนื่องจากเป็นสิ่งที่จำเป็นสำหรับภาษาใด ๆ หากคุณต้องการเพิ่มหน่วยความจำที่เกี่ยวข้องกับภาพในเวลานั้น แต่อีกสิ่งที่คุณต้องทำคือลบภาพออกจากคอลเลกชันและตัวทำลายรูปดูแลส่วนที่เหลือ

ในขณะเดียวกันถ้าฉันเปรียบเทียบกับพูด Java หรือ C # คุณมักจะพบคนที่ต้องปิดไฟล์ด้วยตนเองมีการปลดการเชื่อมต่อซ็อกเก็ตด้วยตนเองตั้งค่าการอ้างอิงวัตถุเป็นโมฆะเพื่อให้พวกเขารวบรวมขยะ ฯลฯ มีหน่วยความจำแบบแมนนวลมากมาย การจัดการทรัพยากรในภาษาเหล่านั้นถ้าคุณถามฉัน ใน C ++ คุณมักไม่จำเป็นต้องunlockมี mutex ด้วยตนเองเนื่องจาก mutex locker จะทำเช่นนั้นให้คุณโดยอัตโนมัติเมื่อ mutex อยู่นอกขอบเขต ตัวอย่างเช่นคุณไม่ควรทำสิ่งนี้ใน C ++:

System.IO.StreamReader file = new System.IO.StreamReader(path);
try
{
    file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
    ...
}
finally
{
    if (file != null)
        file.Close();
}

ไม่จำเป็นต้องทำสิ่งต่าง ๆ เช่นปิดไฟล์ด้วยตนเองใน C ++ พวกเขาจะปิดตัวเองโดยอัตโนมัติทันทีที่พวกเขาออกนอกขอบเขตไม่ว่าพวกเขาจะออกนอกขอบเขตเนื่องจากผลลัพธ์หรือเส้นทางการดำเนินการปกติหรือพิเศษ std::vectorสิ่งที่คล้ายกันสำหรับทรัพยากรหน่วยความจำที่เกี่ยวข้องเช่น รหัสดังกล่าวfile.Close()ข้างต้นมักจะขมวดคิ้วตั้งแต่โดยเฉพาะอย่างยิ่งในบริบทของfinallyบล็อกที่แนะนำทรัพยากรในท้องถิ่นจะต้องมีอิสระด้วยตนเองเมื่อความคิดทั้งหมดรอบ C ++ คือการทำให้เป็นอัตโนมัติ

ในแง่ของการจัดการหน่วยความจำแบบแมนนวลผมว่า C ต้องการค่าสูงสุดปานกลาง Java / C # จำนวนปานกลางและต่ำสุดในกลุ่ม C ++ มีหลายเหตุผลที่การใช้ C ++ ค่อนข้างลำบากเนื่องจากเป็นภาษาที่ยากมากในการควบคุม แต่การจัดการหน่วยความจำไม่ควรเป็นหนึ่งในนั้น ในทางตรงกันข้ามฉันคิดว่ามันเป็นหนึ่งในภาษาที่ง่ายที่สุดในแง่มุมนี้

แน่นอนว่า C ++ จะช่วยให้คุณเริ่มการจัดสรรหน่วยความจำด้วยตนเองและเรียกใช้operator delete/delete[]เพื่อเพิ่มหน่วยความจำด้วยตนเอง นอกจากนี้ยังให้คุณใช้ฟังก์ชัน C เช่นmallocและfree. แต่นั่นเป็นวิธีการเขียนโค้ดแบบโบราณที่ฉันคิดว่าล้าสมัยมานานก่อนที่ผู้คนจะให้เครดิตเนื่องจาก Stroustrup ให้การสนับสนุน RAII ก่อนที่เขาจะประกาศเกียรติคุณตั้งแต่ต้น ดังนั้นฉันจึงไม่คิดว่ามันยุติธรรมที่จะพูดว่า "modern C ++" โดยอัตโนมัติการจัดการทรัพยากรเพราะมันควรจะเป็นวัตถุประสงค์ตลอด คุณไม่สามารถรับข้อยกเว้นด้านความปลอดภัยได้ เป็นเพียงนักพัฒนาที่เข้าใจผิดจำนวนมากในช่วงต้นทศวรรษ 90 ที่พยายามใช้ C ++ เหมือนกับ C กับวัตถุมักจะละเลยการจัดการข้อยกเว้นอย่างสมบูรณ์และไม่ควรใช้วิธีนั้น หากคุณใช้ C ++ ตามที่ตั้งใจไว้เสมอเพื่อใช้งานการจัดการหน่วยความจำนั้นเป็นแบบอัตโนมัติทั้งหมดและโดยทั่วไปไม่ใช่สิ่งที่คุณต้องจัดการด้วยตนเอง (หรือควรจัดการกับ) ด้วยตนเอง


1
Java รุ่นใหม่มี "ลองกับทรัพยากร" ซึ่งจะลบโค้ดยุ่งทั้งหมดในบล็อกในที่สุด มันเป็นสิ่งจำเป็นที่จะต้องมีบล็อกในที่สุด ดูเหมือนว่านักออกแบบได้คัดลอกแนวคิด RAII
kiwiron

0

ขึ้นอยู่กับหัวหน้าฝ่ายเทคนิคอาวุโสในทีม ในบาง บริษัท (รวมถึงของฉัน) ไม่มีแนวคิดที่เรียกว่าสมาร์ทพอยน์ มันถือว่าเป็นแฟนซี ดังนั้นผู้คนจะลบข้อมูลทิ้งไปทั่วสถานที่และมีไดรฟ์สำหรับแก้ไขการรั่วไหลของหน่วยความจำทุก 2 เดือน คลื่นลูกใหม่ของคำสั่งลบมาถึงทุกที่ ดังนั้นขึ้นอยู่กับ บริษัท และประเภทของคนที่ทำงานที่นั่น


1
มีบางสิ่งในสภาพแวดล้อมที่ทำให้คุณไม่สามารถใช้งานauto_ptrและเป็นเพื่อนได้หรือไม่?
Sean McMillan

2
ดูเหมือนว่า บริษัท ของคุณจะไม่เขียนรหัส C ++ คุณกำลังเขียน C.
gbjbaanb
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.