0Pricing
C Academy · บทเรียน

จัดสรรอาร์เรย์

จองหน่วยความจำบนฮีป

จัดสรรอาร์เรย์ เป็นบทเรียน 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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. จัดสรรอาร์เรย์
  2. ขยายด้วย realloc
  3. ชนิดเวกเตอร์ที่นำกลับมาใช้ได้
  4. คืนหน่วยความจำและหลีกเลี่ยงการรั่วไหล
← กลับไปที่ C Academy