อาร์เรย์ การจัดสรรหน่วยความจำใน C (ฟังก์ชัน malloc) การจัดสรรหน่วยความจำแบบไดนามิก


#รวม เป็นโมฆะ * malloc (ขนาด size_t);

คำอธิบาย


ส่งคืนตัวชี้ไปยังไบต์แรกของหน่วยความจำที่ได้รับการจัดสรรจากฮีป


ฟังก์ชัน malloc() ส่งคืนตัวชี้ไปยังไบต์แรกของพื้นที่หน่วยความจำขนาดขนาดที่ได้รับการจัดสรรจากฮีป ถ้ามีหน่วยความจำไม่เพียงพอที่จะตอบสนองการร้องขอ ตัวชี้ null จะถูกส่งกลับ สิ่งสำคัญคือต้องตรวจสอบให้แน่ใจเสมอว่าค่าที่ส่งคืนไม่ใช่ตัวชี้ว่าง การพยายามใช้ตัวชี้ว่างมักจะส่งผลให้ระบบล่มโดยสิ้นเชิง

หากคุณเขียนโปรแกรม 16 บิตสำหรับโปรเซสเซอร์ตระกูล 8086 (เช่น 80486 หรือ Pentium) คอมไพเลอร์ของคุณน่าจะมีฟังก์ชันการจัดสรรหน่วยความจำเพิ่มเติม โดยคำนึงถึงโมเดลหน่วยความจำแบบเซ็กเมนต์ที่ใช้โดยโปรเซสเซอร์เหล่านั้นเมื่อทำงานในโหมด 16 บิต . ตัวอย่างเช่น ฟังก์ชันเหล่านี้อาจเป็นฟังก์ชันที่จัดสรรหน่วยความจำฮีป FAR (ซึ่งตั้งอยู่นอกเซ็กเมนต์ข้อมูลมาตรฐาน) ฟังก์ชันเหล่านี้สามารถกำหนดพอยน์เตอร์ให้กับหน่วยความจำที่มีขนาดใหญ่กว่าหนึ่งส่วนและทำให้หน่วยความจำดังกล่าวว่างได้

เป็นโมฆะฟรี (โมฆะ * ตัวชี้);

ใช้เพื่อเพิ่มหน่วยความจำที่ชี้โดยอาร์กิวเมนต์ของตัวชี้ ขั้นแรกให้จัดสรรหน่วยความจำสำหรับแอปพลิเคชันหลังจากเสร็จสิ้นการทำงานกับหน่วยความจำแล้วจะต้องส่งคืนและฟังก์ชันว่างจะรับผิดชอบในการส่งคืนนี้

_ขนาด

ฟังก์ชัน _msize ส่งกลับขนาดของหน่วยความจำที่จัดสรรจากฮีป:

size_t_msize(เป็นโมฆะ*);

อาร์กิวเมนต์เป็นตัวชี้ไปยังบล็อกของหน่วยความจำ ฟังก์ชัน _msize ส่งกลับขนาดของหน่วยความจำเป็นไบต์ size_t เป็นจำนวนเต็มที่ไม่ได้ลงนาม

มอลลอค

ฟังก์ชัน malloc จัดสรรพื้นที่หน่วยความจำจากฮีป (เช่น พื้นที่ว่างของหน่วยความจำ):

เป็นโมฆะ * malloc (size_t);

อาร์กิวเมนต์ระบุจำนวนไบต์ที่จะจัดสรรจากหน่วยความจำ ฟังก์ชัน malloc ส่งคืนตัวชี้โมฆะไปยังพื้นที่หน่วยความจำที่จัดสรร ซึ่งสามารถส่งไปยังประเภทที่ต้องการได้ หากมีหน่วยความจำว่างสำหรับการจัดสรรน้อยกว่าที่ร้องขอใน size_t ฟังก์ชัน malloc จะส่งคืน NULL

ตัวอย่างการทำงานกับฟังก์ชัน malloc:

/* ผู้แต่ง: @author Subbotin B.P..h> #include #รวม int main(void) ( puts("Memory"); int *pointer; put("เพื่อรับหน่วยความจำ"); pointer = (int*)malloc(2 * sizeof(int)); int memorySize = _msize(pointer); printf("ขนาดหน่วยความจำ = %dn", memorySize); if(pointer == NULL) ( puts("Problems"); return EXIT_FAILURE; ) free(pointer); return EXIT_SUCCESS;

ที่นี่พื้นที่หน่วยความจำได้รับการจัดสรรสำหรับอาร์เรย์ที่ประกอบด้วยสององค์ประกอบประเภท int หากการจัดสรรหน่วยความจำสำเร็จ เราจะเพิ่มพื้นที่หน่วยความจำนี้โดยใช้ฟังก์ชันว่าง

เราได้รับ:

โทรล็อค

ฟังก์ชั่น calloc จัดสรรพื้นที่หน่วยความจำและวางอาร์เรย์เริ่มต้นด้วยศูนย์ในนั้น:

โมฆะ* calloc (size_t, size_t);

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

ตัวอย่างการทำงานกับฟังก์ชัน calloc:

/* ผู้แต่ง: @author Subbotin B.P..h> #include #รวม int main(void) ( puts("Memory"); int *pointer; puts("to get memory"); pointer = (int*)calloc(2, sizeof(int)); int memorySize = _msize(ตัวชี้); printf("ขนาดหน่วยความจำ = %dn", memorySize); if(pointer == NULL) ( puts("Problems"); return EXIT_FAILURE; ) free(pointer); return EXIT_SUCCESS;

ตัวอย่างการจัดสรรหน่วยความจำสำหรับอาร์เรย์ประเภท int ที่มีสององค์ประกอบ องค์ประกอบเหล่านี้ถูกเตรียมใช้งานให้เป็นศูนย์ หากการจัดสรรหน่วยความจำสำเร็จ เราจะเพิ่มพื้นที่หน่วยความจำนี้โดยใช้ฟังก์ชันว่าง

เราได้รับ:

จัดสรรใหม่

ฟังก์ชัน realloc จะเปลี่ยนขนาดของพื้นที่หน่วยความจำที่จัดสรรไว้ก่อนหน้านี้:

เป็นโมฆะ * realloc (โมฆะ *, size_t);

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

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

char place = "อ่าวตับหมู";

และจะมีการจัดสรรหน่วยความจำให้เพียงพอในการจดจำสตริงนี้

หรือเราสามารถเจาะจงมากขึ้นและขอหน่วยความจำจำนวนหนึ่งได้:

จาน int;

คำอธิบายนี้จัดสรรตำแหน่งหน่วยความจำ 100 ตำแหน่ง ซึ่งแต่ละตำแหน่งได้รับการออกแบบมาเพื่อเก็บค่าจำนวนเต็ม

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

/* เพิ่มหน่วยความจำหากจำเป็น */

#รวม

#define STOP " " /* สัญญาณให้หยุดอินพุต */

#define BLOCK 100 /* ไบต์หน่วยความจำ */

#define LIM 40 /* จำกัดความยาวของสตริงอินพุต */

#define MAX 50 /* จำนวนบรรทัดอินพุตสูงสุด */

#define DRAMA 20000 /* ล่าช้านาน */

ร้านถ่าน; /* บล็อกหน่วยความจำต้นทาง */

ชาร์ซิมฟ์; /* ตัวรับสตริงอินพุต */

ถ่าน * จบ; /* ชี้ไปที่จุดสิ้นสุดของหน่วยความจำ */

ถ่าน * เริ่มต้น; /* ชี้ไปที่จุดเริ่มต้นของบรรทัด */

ดัชนี int = 0; /* จำนวนบรรทัดที่ต้องการกรอก */

นับจำนวน; /* ตัวนับ */

ถ่าน *malloc(); /* ตัวจัดสรรหน่วยความจำ */

เริ่ม = เก็บ;

สิ้นสุด = เริ่มต้น + บล็อก - 1;

put("ตั้งชื่อวงซิมโฟนีออเคสตร้าหลายวง");

puts("ป้อนทีละรายการ: กด [enter] ที่จุดเริ่มต้น");

put(" บรรทัดเพื่อทำให้รายการของคุณสมบูรณ์ โอเค ฉันพร้อมแล้ว");

ในขณะที่ (strcmp (fgets (symph, LIM, stdin), STOP) != 0 && ดัชนี< MAX)

( ถ้า(strlen(symph) > สิ้นสุด - เริ่ม)

( /* การดำเนินการหากมีหน่วยความจำไม่เพียงพอที่จะจดจำข้อมูลที่ป้อน */

put("เดี๋ยวก่อน ฉันจะพยายามหาหน่วยความจำเพิ่มเติม");

สิ้นสุด = เริ่มต้น + บล็อก - 1;

สำหรับ (นับ = 0; นับ< DRAMA; count++);

ใส่("เจอแล้ว!"); -

strcpy (เริ่ม, ซิมโฟนี);

เริ่มต้น = เริ่ม + strlen (ซิมโฟนี) + 1;

ถ้า(++index< MAX)

printf("นี่คือ %d. ดำเนินการต่อถ้าคุณต้องการ.n", ดัชนี); -

puts("เอาล่ะ นี่คือสิ่งที่ฉันได้รับ:");

สำหรับ (นับ = 0; นับ< index; count ++)

วาง(เริ่ม);

ข้าว. 15.5. โปรแกรมที่เพิ่มหน่วยความจำตามความต้องการ

นี่คือตัวอย่างโปรแกรม:

ตั้งชื่อวงดนตรีซิมโฟนีออเคสตร้าหลายวง

ป้อนทีละรายการ กด [enter] ที่จุดเริ่มต้น

บรรทัดเพื่อทำให้รายการของเราสมบูรณ์ โอเค ฉันพร้อมแล้ว

ซานฟรานซิสโกซิมโฟนี

นี่คือ 1. ดำเนินการต่อหากคุณต้องการ

ชิคาโกซิมโฟนี

นี่คือ 2. ดำเนินการต่อหากคุณต้องการ

เบอร์ลิน ฟิลฮาร์โมนิก

นี่คือ 3. ดำเนินการต่อหากคุณต้องการ

หอการค้ามอสโก

นี่คือ 4. ดำเนินการต่อหากคุณต้องการ ลอนดอนซิมโฟนี

นี่คือ 5. ดำเนินการต่อหากคุณต้องการ เวียนนา ฟิลฮาร์โมนิก

รอสักครู่. ฉันจะพยายามค้นหาหน่วยความจำเพิ่มเติม

ฉันพบบางส่วน!

นี่คือ 6. ดำเนินการต่อหากคุณต้องการ

พิตส์เบิร์กซิมโฟนี

นี่คือ 7. ดำเนินการต่อหากคุณต้องการ

เอาล่ะ นี่คือสิ่งที่ฉันได้รับ:

ซานฟรานซิสโกซิมโฟนี

ชิคาโกซิมโฟนี

เบอร์ลิน ฟิลฮาร์โมนิก

หอการค้ามอสโก

ลอนดอนซิมโฟนี

เวียนนา ฟิลฮาร์โมนิก

พิตส์เบิร์กซิมโฟนี

ก่อนอื่นเรามาดูกันว่าฟังก์ชันทำอะไร มอลลอค()- ใช้อาร์กิวเมนต์จำนวนเต็มที่ไม่ได้ลงนามซึ่งแสดงถึงจำนวนไบต์ของหน่วยความจำที่ต้องการ ดังนั้น, มอลลอค(BLOCK)ต้องใช้ 100 ไบต์ ฟังก์ชั่นส่งกลับตัวชี้ไปยังประเภท ถ่านจนถึงจุดเริ่มต้นของบล็อกหน่วยความจำใหม่ เราใช้คำอธิบาย

ถ่าน *malloc();

เพื่อเตือนคอมไพเลอร์ว่า มอลลอค()ส่งคืนตัวชี้ไปยังประเภท ถ่าน- ดังนั้นเราจึงกำหนดค่าของตัวชี้นี้ให้กับองค์ประกอบอาร์เรย์ เริ่มต้นโดยใช้ตัวดำเนินการ

เริ่ม = malloc (บล็อก);

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

ข้าว. 15.6. เส้นซิมโฟนีที่เขียนต่อเนื่องกันไปยังอาร์เรย์ของร้านค้า

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

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

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

แต่ตราบใดที่เรามีพอยน์เตอร์ เราก็สามารถทำงานกับสตริงได้ ดังที่ส่วนการพิมพ์ของโปรแกรมแสดงให้เราเห็น

จึงถูกนำมาใช้ มอลลอค()- แต่สมมติว่าคุณต้องการทำงานกับหน่วยความจำเช่น ภายใน, ไม่ ถ่าน- คุณสามารถใช้ที่นี่ได้เช่นกัน มอลลอค()- ต่อไปนี้เป็นวิธีดำเนินการ:

ถ่าน *malloc(); /* ยังคงอธิบายว่าเป็นตัวชี้ไปยังถ่าน */

int *newmem;

newmem = (int *) malloc(l00); /* ใช้การดำเนินการหล่อแบบ */

จำเป็นต้องมี 100 ไบต์อีกครั้ง การดำเนินการ Type Cast จะแปลงค่าที่ส่งคืนโดยตัวชี้ให้เป็นประเภท ถ่านไปยังตัวชี้ไปยังประเภท ภายใน- ถ้าอย่างในระบบของเรา ภายในใช้หน่วยความจำสองไบต์ซึ่งหมายความว่า นิวเมม + 1จะเพิ่มตัวชี้ขึ้นสองไบต์ เช่น ย้ายไปยังจำนวนเต็มถัดไป ซึ่งหมายความว่าสามารถใช้ 100 ไบต์เพื่อเก็บจำนวนเต็ม 50 ตัวได้

ความเป็นไปได้อีกอย่างหนึ่งในการจัดสรรหน่วยความจำคือการใช้ฟังก์ชัน โทรล็อค():

ถ่าน *calloc();

ยาว *newmem;

newmem = (ยาว *) calloc (100, ขนาดของ (ยาว));

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

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

เป็นโมฆะ * malloc (size_t); //ฟังก์ชันการจัดสรรหน่วยความจำ
เป็นโมฆะฟรี (เป็นโมฆะ * memblock); //ฟังก์ชันปล่อยหน่วยความจำ

โดยที่ size_t คือขนาดของพื้นที่หน่วยความจำที่จัดสรรเป็นไบต์ void* เป็นตัวชี้ประเภททั่วไป เช่น ไม่ผูกติดกับประเภทใดประเภทหนึ่งโดยเฉพาะ มาดูกันว่าฟังก์ชันเหล่านี้ทำงานอย่างไรโดยใช้ตัวอย่างการจัดสรรหน่วยความจำสำหรับ 10 องค์ประกอบประเภทคู่

รายการ 4.3. การเขียนโปรแกรมอาร์เรย์แบบไดนามิก

#รวม
#รวม
int หลัก()
{
สองเท่า* ptd;
ptd = (สองเท่า *) malloc (10 * ขนาดของ (สองเท่า));
ถ้า(ptd != NULL)
{
สำหรับ(int i = 0;i ptd[i] = i;
) else printf("ไม่สามารถจัดสรรหน่วยความจำได้");
ฟรี(ptd);
กลับ 0;
}

เมื่อเรียกใช้ฟังก์ชัน malloc() พื้นที่หน่วยความจำที่ต้องการจะถูกคำนวณเพื่อจัดเก็บองค์ประกอบคู่ 10 รายการ เมื่อต้องการทำเช่นนี้ ให้ใช้ฟังก์ชัน sizeof() ซึ่งจะส่งคืนจำนวนไบต์ที่จำเป็นในการจัดเก็บองค์ประกอบคู่หนึ่งรายการ จากนั้นค่าของมันจะถูกคูณด้วย 10 และผลลัพธ์ที่ได้คือปริมาตรขององค์ประกอบสองเท่า 10 รายการ ในกรณีที่ไม่สามารถจัดสรรจำนวนหน่วยความจำที่ระบุด้วยเหตุผลบางประการ ฟังก์ชัน malloc() จะส่งคืน NULL ค่าคงที่นี้ถูกกำหนดไว้ในไลบรารีหลายแห่ง รวมถึง และ หากฟังก์ชัน malloc() ส่งคืนพอยน์เตอร์ไปยังพื้นที่หน่วยความจำที่จัดสรร เช่น ไม่เท่ากับ NULL จากนั้นจะดำเนินการวนซ้ำโดยที่เขียนค่าสำหรับแต่ละองค์ประกอบ เมื่อโปรแกรมออก ฟังก์ชัน free() จะถูกเรียกใช้ ซึ่งจะทำให้หน่วยความจำที่จัดสรรไว้ก่อนหน้านี้ว่างขึ้น อย่างเป็นทางการ โปรแกรมที่เขียนด้วยภาษา C++ เมื่อเสร็จสิ้นจะปล่อยหน่วยความจำที่จัดสรรไว้ก่อนหน้านี้ทั้งหมดโดยอัตโนมัติ และฟังก์ชัน free() ในกรณีนี้สามารถละเว้นได้ อย่างไรก็ตาม เมื่อเขียนโปรแกรมที่ซับซ้อนมากขึ้น คุณมักจะต้องจัดสรรและจัดสรรหน่วยความจำหลายครั้ง ในกรณีนี้ ฟังก์ชัน free() มีบทบาทสำคัญ เนื่องจาก หน่วยความจำที่ไม่ว่างไม่สามารถนำมาใช้ซ้ำได้ ซึ่งจะส่งผลให้เปลืองทรัพยากรคอมพิวเตอร์โดยไม่จำเป็น

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

int var;
int &var2 = var;

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

รายการ 4.4. ตัวอย่างการใช้ลิงค์

โมฆะการแลกเปลี่ยน (int& a, int& b)
{
อุณหภูมิภายใน = a;
ก = ข;
ข = อุณหภูมิ;
}
int หลัก()
{
int agr1 = 10, arg2 = 5;
สลับ(arg1, arg2);
กลับ 0;
}

ในตัวอย่างนี้ ฟังก์ชัน swap() รับอาร์กิวเมนต์สองตัว ซึ่งอ้างอิงถึงตัวแปรสองตัว การใช้ชื่ออ้างอิง a และ b ตัวแปร arg1 และ arg2 ที่กำหนดไว้ในฟังก์ชัน main() และส่งผ่านเป็นพารามิเตอร์ไปยังฟังก์ชัน swap() จะถูกจัดการ ข้อดีของฟังก์ชัน swap() (ซึ่งใช้การอ้างอิงแทนตัวชี้ไปยังตัวแปร) คือช่วยให้มั่นใจได้ว่าฟังก์ชันจะใช้ประเภทตัวแปรที่เหมาะสมเป็นอาร์กิวเมนต์ แทนที่จะเป็นข้อมูลอื่นๆ และการอ้างอิงจะเริ่มต้นอย่างถูกต้องก่อนใช้งาน สิ่งนี้ได้รับการตรวจสอบโดยคอมไพเลอร์เมื่อแปลงข้อความโปรแกรมเป็นโค้ดออบเจ็กต์และสร้างข้อความแสดงข้อผิดพลาดหากการใช้การอ้างอิงไม่ถูกต้อง ไม่เหมือนกับพอยน์เตอร์ การดำเนินการต่อไปนี้ไม่สามารถทำได้โดยใช้การอ้างอิง:

คุณไม่สามารถรับที่อยู่ของลิงก์โดยใช้ตัวดำเนินการที่อยู่ C++
คุณไม่สามารถกำหนดตัวชี้ให้กับลิงก์ได้
คุณไม่สามารถเปรียบเทียบค่าอ้างอิงโดยใช้ตัวดำเนินการเปรียบเทียบ C++
คุณไม่สามารถดำเนินการทางคณิตศาสตร์กับการอ้างอิงได้ เช่น การเพิ่มออฟเซ็ต

  • อธิบายตัวชี้ (พิมพ์ * ตัวชี้; );
  • กำหนดขนาดของอาร์เรย์
  • จัดสรรส่วนของหน่วยความจำเพื่อจัดเก็บอาร์เรย์และกำหนดที่อยู่ของส่วนหน่วยความจำนี้ให้กับตัวชี้

ในการจัดสรรหน่วยความจำใน C++ คุณสามารถใช้โอเปอเรเตอร์ใหม่หรือฟังก์ชันภาษา C - calloc, malloc, realloc ฟังก์ชั่นทั้งหมดอยู่ในไลบรารี stdlib.h

5.2.1 ฟังก์ชันมัลลอค

ฟังก์ชัน malloc จัดสรรไบต์ขนาดหน่วยความจำที่ต่อเนื่องกัน และส่งกลับตัวชี้ไปยังไบต์แรกของก้อนนั้น การเรียกใช้ฟังก์ชันดูเหมือนว่า:

เป็นโมฆะ * malloc (ขนาด size_t);

โดยที่ size คือค่าจำนวนเต็มที่ไม่ได้ลงนาม 1 size_t เป็นประเภทจำนวนเต็มพื้นฐานของภาษา C/C++ ซึ่งได้รับการเลือกในลักษณะที่สามารถจัดเก็บขนาดสูงสุดของอาร์เรย์ประเภทใดก็ได้ที่เป็นไปได้ในทางทฤษฎี บนระบบปฏิบัติการ 32 บิต size_t เป็นตัวเลข 32 บิตที่ไม่ได้ลงนาม (ค่าสูงสุด 2 32 - 1) บนระบบปฏิบัติการ 64 บิต จะเป็นตัวเลข 64 บิตที่ไม่ได้ลงนาม (ค่าสูงสุด 2 64 - 1)ซึ่งกำหนดขนาดของหน่วยความจำที่จัดสรรเป็นไบต์ หากการสำรองหน่วยความจำสำเร็จ ฟังก์ชันจะส่งคืนตัวแปรประเภท void* ซึ่งสามารถแปลงเป็นประเภทพอยน์เตอร์ที่ต้องการได้ หากไม่สามารถจัดสรรหน่วยความจำได้ ฟังก์ชันจะส่งกลับตัวชี้ว่าง NULL

ตัวอย่างเช่น,

สองเท่า *h; //อธิบายพอยน์เตอร์เพื่อเพิ่มเป็นสองเท่า อินท์เค; ซิน>>k; //ใส่จำนวนเต็ม k //จัดสรรพื้นที่หน่วยความจำเพื่อจัดเก็บ k องค์ประกอบประเภทคู่ //ที่อยู่ของส่วนนี้ถูกเก็บไว้ในตัวแปร h h=(double *) malloc (k* ขนาดของ (double)); //h - ที่อยู่ของจุดเริ่มต้นของส่วนหน่วยความจำ //h + 1, h + 2, h + 3 ฯลฯ - ที่อยู่ขององค์ประกอบที่ตามมาของประเภทคู่

5.2.2 ฟังก์ชันคาล็อก

ฟังก์ชัน calloc ได้รับการออกแบบมาเพื่อจัดสรรและล้างหน่วยความจำ

เป็นโมฆะ * calloc (size_t num, size_t size);

การใช้ฟังก์ชันนี้ ส่วนหน่วยความจำจะได้รับการจัดสรร โดยองค์ประกอบจำนวน NUM รายการที่มีขนาดไบต์แต่ละรายการจะถูกจัดเก็บไว้ องค์ประกอบทั้งหมดของพื้นที่ที่เลือกจะถูกรีเซ็ตเป็นศูนย์ ฟังก์ชันจะส่งกลับตัวชี้ไปยังพื้นที่ที่จัดสรรหรือ NULL หากไม่สามารถจัดสรรหน่วยความจำได้

ตัวอย่างเช่น,

ลอย *h; //อธิบายตัวชี้ที่จะลอย อินท์เค; ซิน>>k; //ใส่จำนวนเต็ม k //จัดสรรพื้นที่หน่วยความจำเพื่อจัดเก็บ k องค์ประกอบประเภท float //ที่อยู่ของส่วนนี้ถูกเก็บไว้ในตัวแปร h h=(ลอย *) calloc (k, ขนาดของ (ลอย)); //h คือที่อยู่ของจุดเริ่มต้นของส่วนหน่วยความจำ //h + 1, h + 2, h + 3 ฯลฯ คือที่อยู่ขององค์ประกอบที่ตามมาของประเภท float

5.2.3 ฟังก์ชันจัดสรรใหม่

ฟังก์ชัน realloc ปรับขนาดตำแหน่งหน่วยความจำที่จัดสรรไว้ก่อนหน้านี้ เข้าถึงฟังก์ชันได้ดังนี้:

เป็นโมฆะ * realloc (โมฆะ * p, ขนาด size_t);

โดยที่ p เป็นตัวชี้ไปยังพื้นที่หน่วยความจำซึ่งจำเป็นต้องเปลี่ยนขนาดเป็น size หากที่อยู่ของพื้นที่หน่วยความจำเปลี่ยนแปลงอันเป็นผลมาจากฟังก์ชัน ที่อยู่ใหม่จะถูกส่งกลับตามมา หากค่าจริงของพารามิเตอร์แรกเป็น NULL ฟังก์ชัน realloc จะทำงานในลักษณะเดียวกับฟังก์ชัน malloc นั่นคือจะจัดสรรพื้นที่หน่วยความจำขนาดไบต์

5.2.4 ฟังก์ชั่นฟรี

ฟังก์ชั่นฟรีใช้เพื่อเพิ่มหน่วยความจำที่จัดสรร พูดกับเธอแบบนี้:

เป็นโมฆะฟรี (เป็นโมฆะ * p);

โดยที่ p เป็นตัวชี้ไปยังตำแหน่งหน่วยความจำที่จัดสรรไว้ก่อนหน้านี้โดย malloc, calloc หรือ realloc

5.2.5 ตัวดำเนินการใหม่และลบ

ภาษา C++ มีโอเปอเรเตอร์ใหม่ในการจัดสรรและลบเพื่อเพิ่มหน่วยความจำ

ในการจัดสรรหน่วยความจำเพื่อจัดเก็บองค์ประกอบ n รายการที่เป็นประเภทเดียวกัน โอเปอเรเตอร์ใหม่จะมีรูปแบบ [