สวัสดีและยินดีต้อนรับ. ตอนนี้เราเข้าใจการจัดสรรหน่วยความจำแบบไดนามิกแล้ว
เราต้องใช้งานมัน เราต้องรู้วิธีการทำในโค้ด c จริงๆ
เราจะพูดถึงสามหน้าที่ที่สำคัญจริงๆ คือ
malloc, calloc, realloc
คุณเห็นว่าพวกเขามีชื่อที่จัดสรรหน่วยความจำ
calloc และการจัดสรรใหม่
วิธีที่ง่ายและธรรมดาที่สุดในการจัดสรรหน่วยความจำคือผ่านฟังก์ชันไลบรารีมาตรฐานที่ชื่อว่า
malloc
นี่คือการจัดสรรหน่วยความจำแบบไดนามิกที่รันไทม์
ในการเรียกใช้ฟังก์ชันนี้ คุณต้องรวมไฟล์ส่วนหัว lib มาตรฐาน
คุณระบุจำนวนไบต์ของหน่วยความจำที่คุณต้องการจัดสรรเป็นอาร์กิวเมนต์
สิ่งที่ส่งคืนจากฟังก์ชันนี้คือที่อยู่ของไบต์แรกของหน่วยความจำที่จัดสรร
เนื่องจากคุณได้รับที่อยู่ที่ส่งคืน ตัวชี้จึงเป็นที่เดียวที่จะวางมันไว้
นี่คือเหตุผลที่การจัดสรรหน่วยความจำแบบไดนามิกทำได้โดยใช้แนวคิดของพอยน์เตอร์นี้เท่านั้น
เนื่องจากจะส่งกลับที่อยู่
คุณสามารถใส่ที่อยู่ในตัวชี้เท่านั้น นั่นคือสิ่งที่ตัวชี้เก็บไว้ ตัวชี้เก็บที่อยู่
ต่อไปนี้คือวิธีที่คุณทำ ไวยากรณ์ง่ายๆ
โดยปกติเมื่อสร้างตัวชี้ของคุณ คุณไม่จำเป็นต้องทำ
คุณสามารถสร้างพอยน์เตอร์ของคุณและตั้งค่าให้เป็นโมฆะได้
แล้วในบรรทัดถัดไป คุณอาจจะมัลลอค
แต่นี่คือไวยากรณ์มาตรฐานที่คุณกำลังสร้างตัวชี้ int ตัวชี้ไปยังประเภท
int
แล้วคุณจะเห็นว่าคุณเรียกมัลลอค
และในที่นี้ เรากำลังบอกว่า malloc เราจะสร้าง 100 ไบต์สำหรับ
malloc แล้วเราจะแคสต์ไปที่ตัวชี้ int
เนื่องจาก malloc ส่งคืนเฉพาะที่อยู่ คุณต้องส่งไปยังตัวชี้ปลายทางเนื่องจากที่อยู่นั้นจัดเก็บตัวชี้
int
นี่เป็นวิธีมาตรฐานในการทำ
ตอนนี้คุณกำลังขอหน่วยความจำ 100 ไบต์และกำหนดให้กับที่อยู่ของบล็อกหน่วยความจำให้กับหมายเลข
p
pNumber จะชี้ไปที่ตำแหน่ง int แรกที่จุดเริ่มต้นของ 100 ไบต์ที่ได้รับการจัดสรร
ความหมายก็คือ เนื่องจากจำนวนเต็มมีขนาด 4 ไบต์ต่อชิ้น จึงสามารถเก็บค่าได้
25 int
และอีกครั้ง นี่ถือว่าคุณมี 4 ไบต์
ตอนนี้ขึ้นอยู่กับระบบที่คุณใช้งานอยู่ อาจใหญ่ขึ้นหรือเล็กลง
ดังนั้นคุณควรเห็นปัญหากับสิ่งนี้ รหัสนี้ใช้ไม่ได้กับระบบต่างๆ
เนื่องจากคุณกำลังจัดสรรตามสมมติฐาน ตามสมมติฐานของขนาด
int
ดังนั้นจึงไม่ดีจริง ๆ ที่จะใช้ malloc
ในลักษณะนี้ด้วยจำนวนคงที่ 100
สิ่งที่คุณต้องการทำคือคุณต้องการใช้ตัวดำเนินการ sizeof
ดังนั้นจึงเป็นการดีกว่าที่จะลบสมมติฐานที่ว่า int เป็น 4 ไบต์
หากคุณต้องการจัดสรรพื้นที่สำหรับจำนวนเต็ม 25 ตัวภายในอาร์กิวเมนต์
malloc ให้ระบุจำนวนเต็มที่คุณต้องการจัดสรร
แล้วคูณด้วยขนาดของจำนวนเต็ม
และสิ่งนี้จะทำให้โค้ดพกพาได้สะดวกยิ่งขึ้น
รหัสนี้จะทำงานกับระบบที่แตกต่างกัน ระบบปฏิบัติการที่แตกต่างกัน สถาปัตยกรรมที่แตกต่างกัน
คุณยังคงส่งค่าที่ส่งคืนไปยังที่อยู่ เนื่องจากต้องชี้ไปที่ประเภท
int ดังนั้นคุณจึงพูดว่า int star ข้อแตกต่างเพียงอย่างเดียวคือคุณใช้ตัวดำเนินการ sizeof
ตัวดำเนินการ Sizeof มีความสำคัญมากเมื่อคุณจัดสรรหน่วยความจำโดยใช้ malloc
หรือใช้ calloc หรือ realloc
คุณใช้และต้องการใช้ตัวดำเนินการ sizeof
เสมอสำหรับประเภทที่คุณกำลังจัดสรร แล้วคูณด้วยจำนวนเฉพาะที่คุณต้องการ
ดังนั้นหากคุณต้องการเก็บ 25 int คุณก็ต้องใช้
25
ดังนั้นอาร์กิวเมนต์ของ malloc ข้างต้นจึงแสดงให้เห็นชัดเจนว่าควรมีไบต์ที่เพียงพอสำหรับรองรับค่า
int 25 ค่าประเภท
ดังที่ฉันได้กล่าวไปแล้วให้สังเกตนักแสดง สิ่งนี้จะแปลงที่อยู่ซึ่งส่งคืนโดยฟังก์ชันเป็นตัวชี้ประเภทเป็นตัวชี้
int และ int
Malloc ส่งคืนตัวชี้ประเภท void นั่นคือสิ่งที่ทำให้มันมีประโยชน์มาก
มันส่งคืนที่อยู่นั้น แต่เป็น a เป็นตัวชี้โมฆะ
จำไว้ว่าเราได้พูดถึง void pointers และทำไม void pointers ถึงมีประโยชน์
เพราะตอนนี้คุณสามารถมีฟังก์ชันที่รับค่าพารามิเตอร์ต่างๆ ได้ และสามารถคืนค่า
void pointer ได้ ตอนนี้คุณเห็นพลังของการส่งคืนตัวชี้
void อีกครั้ง แต่หากต้องการใช้งาน
ในการ d เพื่อกำหนดข้อมูลให้กับมันจริง ๆ หากต้องการยกเลิกการอ้างอิง คุณต้องส่งมัน
ถ้าเราไม่ต้องการแคสต์สิ่งนี้ เราอาจบอกว่า void star p number
เราไม่ได้แคสต์ แต่สุดท้ายแล้วเราก็ต้องแคสต์เมื่อเราต้องการยกเลิกการอ้างอิง
แต่นั่นเป็นเหตุผลที่เราต้องแคสต์จากมัลลอค มันส่งคืนที่อยู่และคุณต้องการให้ชี้ไปที่ประเภท
int และส่งคืนประเภทเป็นโมฆะ
คุณสามารถขอจำนวนไบต์ได้
อย่างไรก็ตาม ขึ้นอยู่กับระบบของคุณและจำนวนหน่วยความจำที่คุณมีในระบบของคุณ
ดังนั้นหากคุณพยายามสร้างหรือพยายามขอไบต์จำนวนมากหรือมีข้อ
จำกัด บางอย่างก็อาจล้มเหลว
และเมื่อมันล้มเหลว มันจะคืนค่าเป็น null, malloc จะคืนค่า null
และนี่เป็นสิ่งที่ดีเพราะพอยน์เตอร์เมื่อพอยน์เตอร์ชี้เป็นโมฆะ หมายความว่าพวกมันไม่ได้ชี้ไปที่หน่วยความจำใดๆ
ดังนั้นคุณจึงไม่สามารถเสียหายหรือเปลี่ยนแปลงหน่วยความจำใดๆ
โดยไม่ได้ตั้งใจ
ดังนั้นจึงเป็นความคิดที่ดีเสมอหลังจากที่คุณทำ
malloc ให้ตรวจสอบค่า null ทันทีก่อนใช้งาน เช่นเดียวกับเมื่อคุณกำหนดข้อมูล หรือเหมือนกับเมื่อคุณยกเลิกการอ้างอิงตัวชี้
คุณต้องการให้แน่ใจว่าคุณกำลังชี้ไปที่บางสิ่งบางอย่างจริงๆ
ตรงนี้ เรากำลังจัดสรรหน่วยความจำสำหรับตัวชี้ p number ของเรา
แล้วบอกว่าถ้าไม่ใช่ p number
จำไว้ว่า null เป็นศูนย์
ดังนั้นคุณจึงสามารถใช้ a not กับมันได้ คุณไม่จำเป็นต้องเปรียบเทียบกับค่า null
คุณสามารถเปรียบเทียบกับค่า null ได้ มันทำให้อ่านง่ายขึ้น อาจทำให้ชัดเจนขึ้น
แต่คุณสามารถบอกว่าไม่ใช่เลข p และนั่นมันบอกว่าไม่ใช่หนึ่ง
และค่าว่างเป็นศูนย์ ดังนั้นสิ่งนี้จะตรวจสอบเป็นโมฆะ
และถ้ามันเป็นโมฆะ นั่นหมายความว่าหน่วยความจำไม่สามารถจัดสรรได้
หากคุณไม่สามารถจัดสรรหน่วยความจำในโปรแกรมของคุณได้ แสดงว่าคุณกำลังประสบปัญหา
ดังนั้นสิ่งที่คุณควรทำตามปกติในโค้ดนี้เพื่อจัดการกับความล้มเหลวในการจัดสรรหน่วยความจำคือ
คุณควรยกเลิก คุณควรเรียก exit คุณควรออกจากโปรแกรมของคุณ
เพราะถ้าโปรแกรมของคุณไม่สามารถจัดสรรหน่วยความจำได้ โปรแกรมของคุณก็พัง
โดยปกติแล้ว นี่คือการเรียกคุณว่าอุบัติเหตุ ยกเลิก หากคุณไม่สามารถจัดสรรหน่วยความจำได้
อย่างน้อยเมื่อคุณทำเช่นนี้ คุณสามารถแสดงข้อความยุติโปรแกรมได้
ดีกว่าให้โปรแกรมทำงานต่อเมื่อคุณไม่ได้อยู่
เราไม่สามารถจัดสรรหน่วยความจำได้
เพราะจากนั้นคุณอาจดำเนินการต่อ คุณอาจลองใช้หน่วยความจำนั้น
มันจะเป็นโมฆะ ดังนั้นโปรแกรมจะขัดข้องอยู่ดี แต่คุณไม่จำเป็นต้องรู้สาเหตุ
คุณต้องดูที่สแต็กการโทร จะใช้เวลานานกว่ามากในการแก้ไขข้อผิดพลาดนั้น
ปล่อยหน่วยความจำ. ตอนนี้ฉันบอกว่าเนื่องจากคุณเป็นโปรแกรมเมอร์มีหน้าที่จัดสรรหน่วยความจำ
คุณต้องกำจัดหน่วยความจำเมื่อคุณไม่ได้ใช้อีกต่อไปเพราะหน่วยความจำเป็นทรัพยากรที่สำคัญ โดยเฉพาะอย่างยิ่งในระบบฝังตัว
คุณไม่ควรใช้หน่วยความจำหากไม่ต้องการ จึงต้องปลดปล่อยความจำ
คุณต้องการปลดปล่อยหน่วยความจำเสมอเมื่อไม่ต้องการใช้อีกต่อไป
หน่วยความจำที่คุณจัดสรรบนฮีปจะถูกปล่อยโดยอัตโนมัติเมื่อมีโปรแกรมของคุณอยู่ ซึ่งถือว่าดีเพราะจะช่วยล้างข้อมูลบางส่วน
แต่จะดีกว่ามากที่จะปล่อยหน่วยความจำอย่างชัดเจนเมื่อคุณทำเสร็จแล้ว
แม้ว่าจะเป็นเพียงก่อนที่คุณจะออก
มันสะอาดกว่า ทำให้ว่างเสมอหรือปล่อยหน่วยความจำเสมอหลังจากที่คุณจัดสรร
คุณต้องปฏิบัติตามกฎนี้ นี่เป็นกฎเกณฑ์ที่เข้มงวด
ปล่อยหน่วยความจำเสมอหากคุณจัดสรร
หน่วยความจำรั่วเกิดขึ้นเมื่อคุณจัดสรรหน่วยความจำบางส่วนแบบไดนามิก
และคุณไม่ได้เก็บการอ้างอิงไว้ ดังนั้นคุณจึงไม่สามารถปล่อยได้
บางทีคุณอาจอยู่นอกขอบเขตสำหรับการอ้างอิงที่คุณไม่สามารถ คุณไม่ปล่อยมัน
นั่นเรียกว่าหน่วยความจำรั่ว มีการจัดสรรหน่วยความจำแต่ไม่ได้ใช้อีกต่อไป
สิ่งนี้มักเกิดขึ้นเมื่อคุณอยู่ในลูป และคุณกำลังจัดสรรหน่วยความจำในลูป
คุณอยู่ในวง คุณจัดสรรหน่วยความจำนี้ คุณใช้มันในลูป จากนั้นคุณกระโดดออกจากลูปและคุณจะไม่ปล่อยมันอีกต่อไป
การวนซ้ำแต่ละครั้งจะจัดสรร
ดังนั้นหากต้องการเพิ่มหน่วยความจำที่คุณจัดสรรแบบไดนามิก
คุณต้องยังสามารถเข้าถึงที่อยู่นั้นได้
ดังนั้นโดยปกติคุณต้องการหน่วยความจำว่างเมื่อคุณใช้งานเสร็จแล้วและมักจะอยู่ในวิธีที่คุณจัดสรรไว้
อย่างไรก็ตาม หากคุณกำลังส่งต่อหน่วยความจำนั้นไปยังฟังก์ชันอื่น นั่นเป็นความรับผิดชอบของฟังก์ชันนั้น
แต่โดยปกติคุณต้องการปล่อยหน่วยความจำและฟังก์ชันที่คุณจัดสรร
หากต้องการปล่อยหน่วยความจำสำหรับบล็อกของหน่วยความจำที่จัดสรรแบบไดนามิกซึ่งมีที่อยู่ที่คุณเก็บไว้ในตัวชี้
สิ่งที่คุณต้องทำคือเรียกใช้ฟังก์ชันฟรี
นี่อยู่ใน lib มาตรฐานเช่นกัน คุณเพียงแค่ส่งตัวชี้ไปที่ฟังก์ชันฟรี
และโดยปกติ หลังจากที่คุณผ่านพอยน์เตอร์นั้น คุณต้องการตั้งค่าให้เป็นโมฆะ เพราะนั่นบอกว่าคุณไม่มีหน่วยความจำที่จัดสรรไว้สำหรับตัวชี้นั้น
ฟังก์ชันฟรีมีพารามิเตอร์ที่เป็นทางการของประเภท
void star ดังนั้นคุณสามารถส่งผ่านตัวชี้ประเภทใดก็ได้และจะทำงาน
คุณไม่จำเป็นต้องหล่อหรืออะไรแบบนั้นจริงๆ
ตราบใดที่หมายเลข p มีที่อยู่ที่ส่งคืนเมื่อหน่วยความจำถูกจัดสรร หน่วยความจำทั้งหมดจะว่างสำหรับใช้ต่อไป
โปรแกรมอื่นๆ
สามารถใช้หน่วยความจำนั้นได้ ตอนนี้โปรแกรมของคุณสามารถใช้หน่วยความจำนั้นได้
ซึ่งสำคัญเมื่อคุณอยู่ในระบบฝังตัว
และอย่างที่ฉันได้กล่าวไปแล้ว คุณต้องการตั้งค่าตัวชี้เป็น
null เสมอเพื่อแสดงว่าตัวชี้นั้นไม่ได้ชี้ไปที่สิ่งใดอีกต่อไป
ความทรงจำนั้นได้รับการปลดปล่อย
มีฟังก์ชันที่ดีอีกอย่างที่เรียกว่า calloc
มีข้อได้เปรียบเหนือ malloc สองสามข้อ มันคล้ายกับ malloc มาก แต่สิ่งที่ทำคือจัดสรรหน่วยความจำเป็นองค์ประกอบจำนวนหนึ่งในขนาดที่กำหนด
และยังเริ่มต้นหน่วยความจำด้วย
นั่นคือความแตกต่าง การเริ่มต้น ฉันพูดถึงความสำคัญของการเริ่มต้น
นั่นเป็นเหตุผลที่คุณต้องการเริ่มต้นข้อมูลเสมอ
เพื่อให้คุณเข้าใจว่ามีข้อมูลอยู่ในนั้นที่คุณคาดหวัง
เมื่อคุณไม่ได้กำหนดค่าเริ่มต้นข้อมูล อาจมีข้อมูลที่คุณไม่มีเบาะแส
ดังนั้นให้เริ่มต้นข้อมูลของคุณด้วยบางสิ่งบางอย่างเสมอ
และแคลล็อคดีขึ้นเล็กน้อยเพราะมันทำเพื่อคุณ
ต้องใช้สองอาร์กิวเมนต์ มีสองพารามิเตอร์
จำนวนรายการข้อมูลที่ต้องการพื้นที่ ขนาดของแต่ละรายการข้อมูล
มันถูกประกาศในส่วนหัว lib มาตรฐาน
คุณเรียกมันเหมือนกับที่คุณเรียก Malloc หน้าตาเหมือนกันมาก
ในตัวอย่างนี้ เรากำลังสร้างตัวชี้จำนวนเต็ม
และเรากำลังจัดสรรจำนวนเต็ม 75 ตัวของ sizeof
int ดังนั้นจึงต้องใช้สองพารามิเตอร์
มันสะอาดกว่านิดหน่อยเพราะคุณไม่จำเป็นต้องคูณจริงๆ
ใน malloc คุณต้องทำกิจกรรมขนาด 75 เวลา
ที่นี่คุณแค่พูดว่า 75 คุณกำลังสร้าง
75 int และขนาดสำหรับแต่ละรายการคือ 4 ไบต์หรือสิ่งที่ระบบส่งคืนจากขนาดของตัวดำเนินการ
แต่อีกครั้งที่สำคัญของสิ่งนี้คือมันจะเริ่มต้นข้อมูลทั้งหมดนั้นเช่นกัน ค่าที่ส่งคืนอาจเป็นโมฆะหากไม่สามารถจัดสรรหน่วยความจำนั้นซึ่งในทางกลับกันคุณไม่ควรยกเลิก
แต่มันคล้ายกับการใช้ malloc มาก ยกเว้นข้อดีใหญ่คือการเริ่มต้นนี้
int ทั้งหมดถูกตั้งค่าเริ่มต้นเป็นศูนย์ และนั่นเป็นเรื่องใหญ่ ข้อได้เปรียบที่ยิ่งใหญ่
นอกจากนี้ยังใช้งานกับพารามิเตอร์ทั้งสองได้ง่ายขึ้นเล็กน้อย
มาพูดถึงฟังก์ชันอื่นที่เรียกว่า realloc
ฟังก์ชัน realloc ช่วยให้คุณสามารถใช้ซ้ำหรือขยายหน่วยความจำที่คุณจัดสรรไว้ก่อนหน้านี้โดยใช้
malloc หรือ calloc
ดังนั้นนี่คือวิธีการเปลี่ยนจำนวนหน่วยความจำที่จัดสรรในขณะที่คุณใช้งานแบบไดนามิก
ดังนั้น ในตอนแรกคุณสามารถสร้างหน่วยความจำได้มาก และจากนั้นคุณก็ตระหนักว่า
หน่วยความจำไม่เพียงพอ สิ่งที่คุณทำได้คือเรียก realloc และนี่จะจัดสรรหน่วยความจำใหม่
คาดหวังค่าอาร์กิวเมนต์สองค่า ตัวชี้ที่มีที่อยู่ซึ่งก่อนหน้านี้ถูกเรียกใช้โดยการเรียก
malloc
ดังนั้นคุณจึงมีพอยน์เตอร์ที่มีการจัดสรรหน่วยความจำหรือ calloc แล้วตามด้วยขนาดและไบต์ของหน่วยความจำใหม่ที่คุณต้องการจัดสรร
ดังนั้น นี่จะจัดสรรจำนวนหน่วยความจำที่คุณระบุโดยอาร์กิวเมนต์ที่สอง
นั่นคืออาร์กิวเมนต์ที่สอง โดยจะถ่ายโอนเนื้อหาของหน่วยความจำที่จัดสรรไว้ก่อนหน้านี้
ซึ่งอ้างอิงโดยตัวชี้ ดังนั้น มันจะรู้โดยอัตโนมัติว่าหน่วยความจำที่คุณจัดสรรไว้ก่อนหน้านี้มากเพียงใด
เนื่องจากคุณส่งผ่านตัวชี้
จากนั้นจะเพิ่มหน่วยความจำที่จัดสรรใหม่เข้าไป
และส่งคืนตัวชี้เป็นโมฆะไปยังหน่วยความจำใหม่
ดังนั้นคุณต้องสร้างมันใหม่เมื่อคุณเรียก realloc เช่นเดียวกับที่อื่น
มันจะคืนค่า null หากคุณไม่สามารถ realloc ได้ ซึ่งอาจเป็นข้อผิดพลาดร้ายแรงอีกครั้ง
และคุณควรยกเลิก
คุณลักษณะที่สำคัญที่สุดของการดำเนินการนี้คือ realloc
รักษาเนื้อหาของพื้นที่หน่วยความจำดั้งเดิม คุณเพียงแค่ขยายหน่วยความจำนั้น
อาจมีการแยกส่วนเนื่องจากคุณอาจไม่สามารถทำตามลำดับได้ แต่คุณยังมีหน่วยความจำทั้งหมดที่คุณสามารถกำหนดให้กับข้อมูลได้ในขณะนี้
มาดูตัวอย่างกัน
ในตัวอย่างนี้ เราจะใช้ malloc แล้วเราจะจัดสรรหน่วยความจำใหม่ จากนั้นเราจะปล่อยให้มันว่าง
ที่นี่เรากำลังสร้างตัวชี้อักขระ
เราไม่ได้เริ่มต้นให้เป็นโมฆะเราควรจะเป็น
แต่ไม่มีหน่วยความจำที่จัดสรรสำหรับสิ่งที่ชี้ไป
มีหน่วยความจำที่จัดสรรให้จัดเก็บพอยน์เตอร์ซึ่งเป็นเพียงที่อยู่
แต่ถ้าคุณพยายามไปยังที่อยู่นั้น โปรแกรมของคุณจะเป็นโฮสต์
สิ่งที่คุณทำคือคุณเรียกว่ามัลลอค
ในที่นี้เรากำลังพูดถึง malloc 15
สิ่งนี้จะสร้าง 15 ไบต์สำหรับตัวชี้อักขระ
เราโยนมันเพราะมันส่งคืนตัวชี้เป็นโมฆะ ดังนั้น str เป็นตัวชี้ที่มีการจัดสรรหน่วยความจำสำหรับสิ่งที่ชี้ไป
จากนั้นเราสามารถใช้ str copy เพื่อส่งข้อมูลบางอย่างไปยังสิ่งที่ชี้ไป
สตริง และเราพิมพ์สตริงในที่อยู่
ทีนี้ เราก็รู้ว่าสิ่งที่เราจัดสรร 15 ไบต์นั้นไม่ใหญ่พอ
ดังนั้นเราจึงเรียก realloc และเราส่งผ่านตัวชี้ซึ่งเป็น
str และเราต้องการ realloc เพิ่มอีก 25 ไบต์ จากนั้นจะคืนค่าจุดที่เป็นโมฆะเนื่องจากเราต้องส่งอีกครั้ง
ตอนนี้เราจะยังอยู่ในความทรงจำของเจสัน
ตอนนี้เราสามารถเรียก string concatenated และต่อกับ string com ได้ ดังนั้นตอนนี้ก็จะเป็น
Jason com แล้วเราก็พิมพ์ออกมา
และสุดท้าย แต่ไม่ท้ายสุด อาจเป็นสิ่งที่สำคัญที่สุดของสไลด์นี้
ดังนั้นเราจึงไม่มีหน่วยความจำรั่ว คือเราโทรฟรี
โทรฟรีเสมอเมื่อคุณโทรหา malloc
ลองมาดูตัวอย่างนี้ภายในบล็อคโค้ด
นี่คือตัวอย่างโค้ดของเราในเครื่องมือแก้ไขบล็อกโค้ดของเรา
และสิ่งแรกที่คุณควรสังเกตคือ เรากำลังรวมไฟล์ส่วนหัว
lib มาตรฐาน เพราะนั่นคือที่ที่ฟังก์ชัน malloc ของเรา และฟังก์ชัน realloc
ของเราอยู่ในนั้น เช่นเดียวกับฟังก์ชันฟรีของเรา
เนื่องจากเราใช้ฟังก์ชัน str การต่อและคัดลอก
เราจึงรวมสตริงด้วย ชม.
ตอนนี้ในบรรทัดที่แปด เราจะสร้างตัวชี้ตัวละครของเรา
ไม่มีหน่วยความจำที่จัดสรรไว้สำหรับมัน
เราควรเริ่มต้นสิ่งนี้เป็นโมฆะเพราะมันยังไม่ชี้ไปที่สิ่งใด
ในบรรทัดที่ 11 เราเรียก malloc
และเราน่าจะบอกว่าขนาดของถ่านถึง 15 เท่า ในกรณีที่ขนาดของไบต์ของถ่านแตกต่างกัน
จากนั้นเราจึงใส่มันลงในตัวชี้อักขระเนื่องจาก
malloc คืนค่าเป็นโมฆะ
จากนั้นเราก็คัดลอก
หากเราพยายามคัดลอกข้อมูลนี้และไม่ได้ดำเนินการใดๆ ในบรรทัดที่ 11 โปรแกรมจะขัดข้องเนื่องจากเราไม่มีหน่วยความจำที่จัดสรรไว้สำหรับสตริงที่ชี้ไป
จากนั้นเราก็พิมพ์สตริงและที่อยู่
ตอนนี้เราเรียก realloc
เราจำเป็นต้องเก็บข้อมูลมากกว่า 15
ไบต์ ดังนั้นเราจะทำการ realloc ด้วย 25 ไบต์ และเราอาจต้องการทำขนาดของถ่านอีกครั้งเพื่อให้สอดคล้องกัน
เราโยนสิ่งนี้แล้วเชื่อมไปยังตำแหน่งหน่วยความจำที่มีอยู่ซึ่งมีเจสัน
com และเราจะพิมพ์เจสันออกมา คอม
และสุดท้ายแต่ไม่ท้ายสุด ในบรรทัดที่ 20 เราทำให้หน่วยความจำนั้นว่างขึ้น
ซึ่งสำคัญมาก
ไปข้างหน้าและดำเนินการนี้ และสิ่งที่คุณเห็นก็คือว่า
เมื่อเราพิมพ์ออกมาเป็นครั้งที่สอง เราก็มีการต่อกัน
ดังนั้นสตริงแรกของเรา
เราได้จัดสรรหน่วยความจำแล้ว และมันคือที่อยู่ 000C2918
จากนั้นเราสร้างที่อยู่ใหม่โดยจัดสรรใหม่และใช้ขนาดที่มีอยู่ของตัวชี้ที่เราส่งต่อเป็นอาร์กิวเมนต์
ดังนั้น 000C0CD8 จึงมีการจัดสรรข้อมูลมากขึ้น
ข้อมูลที่มีอยู่ในเจสันและอีก
25 ไบต์
ดังนั้นสิ่งที่คุณสังเกตเห็นก็คือการต่อเชื่อมเข้าด้วยกัน
เพราะเมื่อเราจัดสรรใหม่
เราใส่เนื้อหาที่เจสันไว้ในความทรงจำนั้น แล้วเราก็ขยายมันออกไป
ข้อดีมากมายในการใช้ malloc เหล่านี้ การโทรแบบ calloc และการโทร realloc ฟรี
คุณต้องการใช้สิ่งเหล่านี้ คุณต้องการเข้าใจสิ่งเหล่านี้ ฟังก์ชั่นที่ค่อนข้างง่ายในการใช้งาน
ในสไลด์สุดท้ายของเรา มาดูหลักเกณฑ์บางอย่างกัน
คุณต้องหลีกเลี่ยงการจัดสรรหน่วยความจำจำนวนเล็กน้อยจำนวนมาก ซึ่งไม่มีประสิทธิภาพ
เมื่อคุณจัดสรรหน่วยความจำบนฮีป
หน่วยความจำจะมีค่าใช้จ่ายบางส่วน
และถ้าคุณจัดสรรหน่วยความจำขนาดเล็ก มันจะมีค่าใช้จ่ายมากกว่าการจัดสรรบล็อกที่ใหญ่กว่าให้น้อยลง
ดังนั้นจงจัดสรรหน่วยความจำที่คุณต้องการ
แต่อย่าทำทุกสองคำสั่งด้วยการจัดสรรใหม่ ทำเป็นชิ้นใหญ่
เก็บไว้ในหน่วยความจำเท่านั้นตราบเท่าที่คุณต้องการ หน่วยความจำเป็นทรัพยากรที่หายาก
เมื่อมันอยู่บนกองก็หายากมากขึ้น
ดังนั้นเมื่อคุณใช้บล็อกหน่วยความจำเสร็จแล้ว โทรฟรี
ตรวจสอบให้แน่ใจว่าคุณจัดเตรียมหน่วยความจำสำหรับการปล่อยหน่วยความจำที่คุณจัดสรรไว้เสมอ ตัดสินใจว่าจะปล่อยหน่วยความจำไว้ที่ใดในโค้ดของคุณเมื่อคุณเขียนโค้ดที่จัดสรรไว้
ตรวจสอบให้แน่ใจว่าคุณมีสิทธิ์เข้าถึงตัวชี้นั้น
หากคุณต้องการทำให้ตัวชี้เป็นแบบโกลบอล คุณจำเป็นต้องทำอย่างนั้น
แต่โดยปกติทุกที่ที่คุณจัดสรรในฟังก์ชันนั้น คุณควรปล่อยในฟังก์ชันนั้น
หากคุณมีฟังก์ชันอื่นๆ ที่ปล่อยหน่วยความจำให้คุณ
แสดงว่าคุณถือว่าไม่ดี มีการมีเพศสัมพันธ์และการขึ้นต่อกันมากเกินไป
ผู้สร้างควรเป็นคนที่ลบออก
อย่าเอาความรับผิดชอบไปไว้บนหน้าที่อื่นและอื่น ๆ
ตรวจสอบให้แน่ใจว่าคุณไม่ได้เขียนทับที่อยู่ของหน่วยความจำที่คุณได้จัดสรรไว้บนฮีปโดยไม่ได้ตั้งใจก่อนที่คุณจะปล่อยมัน
ซึ่งจะทำให้หน่วยความจำรั่ว
ดังนั้นหากคุณพยายามเขียนไบต์มากเกินไปหรือหากคุณมีโอเวอร์โฟลว์
คุณอาจมีปัญหา
ดังนั้นโปรดใช้ความระมัดระวังเป็นพิเศษเมื่อคุณจัดสรรหน่วยความจำภายในลูป
เนื่องจากอาจทำให้เกิดปัญหาในบัฟเฟอร์ล้นได้
ฉันหวังว่านี่จะเป็นประโยชน์ การจัดสรรหน่วยความจำแบบไดนามิกเป็นเรื่องใหญ่
ฉันจะให้คำท้าที่จะช่วยให้คุณคุ้นเคยกับสิ่งนี้มากขึ้น
แต่ให้แน่ใจว่าคุณเข้าใจแนวคิดนี้ ขอขอบคุณ.