จัดสรรอาร์เรย์
จองหน่วยความจำบนฮีป
จัดสรรอาร์เรย์ เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
เหตุใดจึงต้องใช้แถวลำดับแบบพลวัต
แถวลำดับปกติมีขนาดตายตัวซึ่งกำหนดขณะคอมไพล์ แต่บ่อยครั้งเราไม่ทราบว่าต้องใช้กี่สมาชิกจนกว่าโปรแกรมจะเริ่มทำงาน
แถวลำดับแบบพลวัตแก้ปัญหานี้ได้ โดยขอพื้นที่หน่วยความจำหนึ่งบล็อกจากระบบปฏิบัติการขณะโปรแกรมทำงานผ่าน malloc แล้วใช้ตัวแปรกำหนดขนาด
รู้จัก malloc
malloc (การจัดสรรหน่วยความจำ) อยู่ใน <stdlib.h> คุณส่งจำนวนไบต์ให้ฟังก์ชันนี้ แล้วฟังก์ชันจะคืนตัวชี้ไปยังบล็อกนั้น หรือคืนค่า NULL หากไม่สำเร็จ
หน่วยความจำมาจากฮีปและจะคงอยู่จนกว่าคุณจะคืนหน่วยความจำด้วย free
int *p = malloc(10 * sizeof(int));กำหนดขนาดด้วย sizeof
อย่ากำหนดจำนวนไบต์ตายตัว ให้ใช้ sizeof เพื่อให้โค้ดทำงานถูกต้องในแพลตฟอร์มต่าง ๆ
หากต้องการจัดสรรพื้นที่สำหรับจำนวนเต็ม n ตัว ให้คูณ n ด้วย sizeof(int) รูปแบบที่ใช้กันทั่วไปคือ n * sizeof(*p) ซึ่งใช้ชนิดของตัวชี้เอง
int *p = malloc(n * sizeof(*p));ตรวจสอบ NULL เสมอ
หากระบบมีหน่วยความจำไม่พอ malloc จะคืนค่า NULL การอ่านค่าผ่านตัวชี้ NULL จะทำให้โปรแกรมหยุดทำงาน
ตรวจสอบผลลัพธ์ก่อนนำไปใช้ นิสัยเพียงข้อนี้ช่วยป้องกันความล้มเหลวที่แก้ไขได้ยากจำนวนมาก
int *p = malloc(n * sizeof(*p));
if (p == NULL) {
fprintf(stderr, "out of memory\n");
return 1;
}การจัดสรรพื้นที่แบบสมบูรณ์
นี่คือตัวอย่างโปรแกรมเต็มรูปแบบที่จัดสรรพื้นที่สำหรับจำนวนเต็ม 5 ตัว กำหนดค่าให้ตัวเลขเหล่านั้น และพิมพ์ออกมา
สังเกตความสมดุล: เรียก malloc ตอนเริ่มต้น และเรียก free ตอนจบ
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 5;
int *a = malloc(n * sizeof(*a));
if (!a) return 1;
for (int i = 0; i < n; i++) a[i] = i * i;
for (int i = 0; i < n; i++) printf("%d\n", a[i]);
free(a);
return 0;
}malloc ไม่ได้กำหนดค่าเป็นศูนย์
หน่วยความจำจาก malloc ยังไม่ได้กำหนดค่าเริ่มต้น กล่าวคือมีค่าขยะที่หลงเหลืออยู่ก่อนหน้า
การอ่านค่าก่อนเขียนจะได้ค่าที่คาดเดาไม่ได้ ให้กำหนดค่าให้สมาชิกทุกตัวก่อนอ่านเสมอ
int *a = malloc(3 * sizeof(*a));
/* a[0], a[1], a[2] hold garbage here */
a[0] = 10;calloc กำหนดค่าเป็นศูนย์ให้คุณ
calloc(count, size) จัดสรรพื้นที่สำหรับสมาชิกจำนวน count ตัว โดยแต่ละตัวมีขนาด size ไบต์ และกำหนดทุกไบต์เป็นศูนย์
ใช้เมื่อคุณต้องการแถวลำดับที่สะอาดและมีค่าเป็นศูนย์ทั้งหมด นอกจากนี้ยังช่วยป้องกันค่าล้นขณะคูณขนาด
int *a = calloc(5, sizeof(*a));
/* every element is now 0 */การใช้ calloc จริง
โปรแกรมนี้ใช้ calloc และยืนยันว่าแถวลำดับเริ่มต้นด้วยค่าศูนย์ก่อนที่เราจะเปลี่ยนแปลงค่า
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 4;
int *a = calloc(n, sizeof(*a));
if (!a) return 1;
for (int i = 0; i < n; i++) printf("%d\n", a[i]);
free(a);
return 0;
}การใช้ดัชนีกับบล็อก
ตัวชี้ไปยังบล็อกบนฮีปทำงานเหมือนชื่อแถวลำดับทุกประการ คุณสามารถใช้ a[i] เพื่ออ่านและเขียนสมาชิกใด ๆ ตั้งแต่ 0 ถึง n-1
ภายในแล้ว a[i] มีความหมายเหมือนกับ *(a + i)
int *a = malloc(3 * sizeof(*a));
a[0] = 1;
*(a + 1) = 2; /* same as a[1] = 2 */
a[2] = 3;ระวังขอบเขต
หากคุณจัดสรรสมาชิกจำนวน n ตัว ดัชนีที่ถูกต้องคือ 0 ถึง n-1 การเขียนไปยัง a[n] เป็นพฤติกรรมที่ไม่ได้กำหนด
C จะไม่ตรวจสอบขอบเขตให้คุณ ดังนั้นข้อผิดพลาดแบบเกินไปหนึ่งตำแหน่งอาจทำให้หน่วยความจำเสียหายโดยไม่แสดงอาการ
int *a = malloc(3 * sizeof(*a));
a[2] = 99; /* OK, last valid index */
/* a[3] = 0; BUG: out of bounds */อ่านขนาดขณะโปรแกรมทำงาน
จุดเด่นที่แท้จริงคือ ขนาดอาจมาจากข้อมูลนำเข้า ไฟล์ หรือการคำนวณก็ได้ โค้ดเดียวกันสามารถจัดสรรสมาชิก 2 ตัวหรือ 2 ล้านตัว
#include <stdio.h>
#include <stdlib.h>
int main(void) {
int n = 6; /* could be scanf'd */
long *a = malloc(n * sizeof(*a));
if (!a) return 1;
long sum = 0;
for (int i = 0; i < n; i++) { a[i] = i + 1; sum += a[i]; }
printf("%ld\n", sum);
free(a);
return 0;
}ตรวจสอบความเข้าใจ
ทดสอบความเข้าใจของคุณเกี่ยวกับการจัดสรรพื้นที่
ทบทวน
คุณสามารถจัดสรรแถวลำดับแบบพลวัตด้วย malloc(n * sizeof(*p)) หรือจัดสรรแบบเติมศูนย์ด้วย calloc(n, sizeof(*p))
ตรวจสอบ NULL เสมอ จำไว้ว่า malloc ทิ้งค่าขยะไว้ ใช้ดัชนีตั้งแต่ 0 ถึง n-1 และจับคู่การจัดสรรทุกครั้งกับ free ขั้นต่อไปคุณจะเรียนรู้การปรับขนาดบล็อกโดยยังคงรักษาข้อมูลเดิมไว้
คำถามที่พบบ่อย
บทเรียน “จัดสรรอาร์เรย์” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “จัดสรรอาร์เรย์” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “จัดสรรอาร์เรย์”
จองหน่วยความจำบนฮีป คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน
บทเรียน “จัดสรรอาร์เรย์” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม
ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ