หน่วยความจำรั่วเป็นปัญหาสำหรับผู้ใช้อัญมณี ติดตามได้ยากและอาจนำไปสู่ต้นทุนโครงสร้างพื้นฐานที่มีราคาแพง
หน่วยความจำรั่วภายในส่วนขยาย C ยิ่งแย่ลงไปอีก คุณจะเห็นเครื่องมือและบทความมากมายเกี่ยวกับการค้นหารอยรั่วใน Ruby อย่างไรก็ตาม คุณไม่มีสิทธิ์เข้าถึงภายในแบบเดียวกันใน C.
การใช้ 00 อย่างไร้เดียงสา อาจทำให้หน่วยความจำรั่วได้ ควรใช้ 18 จะดีกว่ามาก แทน ดังนั้น หากคุณเป็นผู้เขียนส่วนขยาย C โปรดอ่านต่อเพื่อประโยชน์ของนักพัฒนาที่จะใช้อัญมณีของคุณ
มาเริ่มกันเลย!
ปัญหาเกี่ยวกับ 23 และค
37รหัส> สามารถเป็นเครื่องมือที่ยอดเยี่ยมเมื่อคุณต้องการโต้ตอบระหว่าง Ruby และส่วน C ของไลบรารีของคุณ แต่ต้องเขียน C เพียงเล็กน้อยเท่านั้น
อย่างไรก็ตาม เมื่อคุณรัน 40 คุณไม่ได้อยู่ใน C อีกต่อไปแล้ว ซึ่งทุกอย่างตรงไปตรงมา คุณสามารถถูกทิ้งไว้ในน้ำโคลนได้หากฟังก์ชันที่เรียกว่า:
- เปลี่ยนคำจำกัดความโดยสิ้นเชิงในระหว่างรันไทม์
- ยกสาย
เบอร์ 1 เป็นตัวจับง่ายที่สุด คุณอาจจะจบลงด้วย segfault และหากชุดการทดสอบของคุณสมบูรณ์เพียงพอ คุณควรตรวจสอบก่อนที่จะเผยแพร่
อย่างไรก็ตาม อย่างหลังอาจทำให้หน่วยความจำรั่วและทำให้โค้ดเบสของคุณอ่านยากขึ้น มาดูกันตอนนี้เลย
เพิ่ม Ruby ทำให้เกิดการรั่วไหลของหน่วยความจำ C
กลไกการยกของ Ruby ข้ามระหว่างส่วนต่างๆ ของโค้ดจากขอบเขตหนึ่งไปยังพาเรนต์แรกที่ตรวจพบข้อผิดพลาด สิ่งนี้ถูกนำไปใช้ใน MRI โดยใช้ 52 และ 69รหัส> .
หากคุณสนใจเกี่ยวกับวิธีการสร้างสิ่งนี้ โปรดอ่านบท Evaluator ใน Ruby Hacking Guide โดยสรุป เมื่อคุณใช้ 72 บล็อก คุณ 89 และเมื่อคุณเพิ่มภายในบล็อกนี้ คุณจะ 90 ไปยังตำแหน่งที่บันทึกไว้
ดังนั้นหากฟังก์ชันถูกยกขึ้นด้วย 105 รหัส C ที่ถูกเรียกหลังจากนั้นไม่เคยดำเนินการ
ตัวอย่างด้านล่างแสดงให้เห็นถึงการรั่วไหลที่อาจเกิดขึ้น ถ้า 113 เพิ่มขึ้น มันจะรั่วไหล
แน่นอนว่าตัวอย่างข้างต้นค่อนข้างงี่เง่า — คุณสามารถกลับด้านส่วนการประมวลผล Ruby และ freeing ได้ อย่างไรก็ตาม สิ่งนี้ไม่สามารถทำได้เสมอไป และส่วนฟังก์ชันที่ยาวขึ้นก็สามารถเชื่อมโยงกันได้มากขึ้น
การใช้ 122 ใน Ruby
หากคุณใช้ Ruby คุณสามารถเขียนตัวอย่างข้างต้นโดยใช้131แทนได้ :
API นี้ยังมีให้บริการในภาษา C ด้วย 145 และ 154รหัส> :
อย่างไรก็ตาม ขั้นตอนนี้อาจยุ่งยากเล็กน้อย และหากคุณต้องการเพิ่ม 169 บล็อกไปที่ปาร์ตี้ มันจะอ่านน้อยลงมาก ฉันขอแนะนำให้อ่าน 'A Rubyist's Walk along the C-side (ตอนที่ 8):ข้อยกเว้นและการจัดการข้อผิดพลาด' ของ Peter Zhu หากคุณต้องการใช้ 173 API ใน C.
การใช้ 187 สำหรับค
มีอีกทางเลือกหนึ่ง ก่อนอื่น เรามาดูกันว่ามันจะมีลักษณะอย่างไรใน Ruby:
สิ่งนี้ดูแปลกใน Ruby แต่เป็นเวิร์กโฟลว์ที่เหมาะกับ C มาก MRI มี API สำหรับสิ่งนั้น 199 และฟังก์ชัน C มีลักษณะดังนี้:
วิธีการข้างต้นจะทำให้เกิดข้อผิดพลาด Ruby อีกครั้งหลังจากมีของว่างฟรี
โปรดทราบว่าเราสามารถเลือกที่จะเพิกเฉยต่อข้อผิดพลาดได้โดยใช้ anempty 208 บล็อกใน Ruby:
คำเตือน: หากคุณไม่ก่อให้เกิดข้อผิดพลาด 210 ขั้นตอนสำคัญ ดังนั้นคุณจึงไม่ต้องเก็บข้อมูลข้อผิดพลาดที่ผู้ใช้ไม่ควรทราบ ป>
หรือคุณสามารถเลือกที่จะแจ้งข้อผิดพลาดตามเงื่อนไขได้ เช่น 221 :
คุณสามารถพิจารณา 234 ได้จริงๆ เช่นเดียวกับ 248 ตัวแปรร่วม
ทั้งหมดนี้เยี่ยมยอด แต่เมื่อเหลือเพียง 258 เท่านั้น เราจึงสามารถลดความซับซ้อนของ API นั้นได้
แนวคิดโดยรวมเบื้องหลังการใช้ 260 API เมื่อมีฟังก์ชั่นเพิ่มคือเพิ่มความสามารถในการอ่าน คุณไม่จำเป็นต้องตรวจสอบว่าฟังก์ชันสามารถเพิ่มได้หรือไม่ คุณถือว่าทำได้ และใช้สถานะเพื่อทำงานกับฟังก์ชันนั้น
272รหัส> ข้อเสนอ
มาแยก 281 กัน เนื่องจากเป็นสิ่งเดียวที่อันตราย วิธีการใช้ นี่คือ API ที่จะทำเช่นนั้น:
API นี้เหมือนกับ 296 โดยมี 309 จาก 313 . ดังนั้นการใช้งานจึงค่อนข้างตรงไปตรงมา:
API นี้ยังไม่มีให้บริการใน Ruby และอาจไม่มีให้บริการเลย คุณสามารถรับได้จาก RGeo (MIT LICENSE)
ตัวอย่างในโลกแห่งความเป็นจริง
หากคุณต้องการดูตัวอย่างในโลกแห่งความเป็นจริง ฉันขอแนะนำให้คุณอ่าน RGeocodebase เนื่องจากเราเพิ่งเปลี่ยนมาใช้เวอร์ชันเต็ม 327 . เรายังมีฟังก์ชันบางอย่าง เช่น 331 ที่เผยแพร่สถานะนี้เพื่อการใช้งานที่ง่ายขึ้น ฟังก์ชันนี้เป็นจุดเริ่มต้นที่ดีในการเริ่มต้นขุดค้น
อย่าลังเลที่จะเปิดประเด็นใน RGeo เพื่อหารือเกี่ยวกับตัวเลือกที่เราทำเพิ่มเติม
สรุป
ในโพสต์นี้ เราเตือนไม่ให้ใช้ 349 ด้วย C เพราะอาจทำให้หน่วยความจำรั่วได้ เราสำรวจโดยใช้ 357 หรือ 364 แทน.
ขอให้สนุกกับการเขียนโค้ด!
ปล. หากคุณต้องการอ่านโพสต์ Ruby Magic ทันทีที่เผยแพร่ สมัครรับจดหมายข่าว Ruby Magic ของเราและไม่พลาดแม้แต่โพสต์เดียว! ป>
ยูลิสซี บูโอโนโม
Ulysse ผู้เขียนรับเชิญของเราคืออดีตนักพัฒนา Ruby ในอุตสาหกรรมที่อุทิศเวลาส่วนใหญ่ให้กับการเดินทางรอบโลก เวลาว่างของเขาทุ่มเทให้กับ RGeo และ Ruby และเขาชอบที่จะปรับแต่งระบบภายในของ Ruby
บทความทั้งหมดโดย Ulysse Buonomo