C Academy · บทเรียน

malloc และ free

จัดสรรหน่วยความจำบนฮีป

บทเรียน 1 จาก 413 ขั้นตอน

malloc และ free เป็นบทเรียน C Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

ฮีป

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

คุณจัดการหน่วยความจำบนฮีปด้วยตัวเองโดยใช้ฟังก์ชันจาก <stdlib.h>

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 99;
    printf("%d\n", *p);
    free(p);
    return 0;
}

การเรียกใช้ malloc

malloc(size) จองพื้นที่ขนาด size ไบต์ และคืนค่าตัวชี้ไปยังพื้นที่นั้น หรือคืนค่า NULL หากล้มเหลว

หน่วยความจำนี้เป็นแบบ ยังไม่ได้กำหนดค่าเริ่มต้น เนื้อหาจึงไม่แน่นอน

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 7;
    printf("value = %d\n", *p);
    free(p);
    return 0;
}

การกำหนดขนาดด้วย sizeof

กำหนดขนาดการจองด้วย sizeof เสมอ เพื่อให้โค้ดทำงานถูกต้องบนทุกแพลตฟอร์ม

การเขียน sizeof(*p) จะเชื่อมขนาดเข้ากับชนิดของตัวชี้โดยอัตโนมัติ

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    double *p = malloc(sizeof(*p));
    *p = 3.14;
    printf("%f\n", *p);
    free(p);
    return 0;
}

ตรวจสอบ NULL เสมอ

หากการจองล้มเหลว malloc จะคืนค่า NULL การเข้าถึงค่าผ่านตัวชี้นี้จะทำให้โปรแกรมหยุดทำงาน

ตรวจสอบผลลัพธ์ก่อนนำไปใช้งาน

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    if (p == NULL) {
        printf("allocation failed\n");
        return 1;
    }
    *p = 5;
    printf("ok: %d\n", *p);
    free(p);
    return 0;
}

การจองพื้นที่สำหรับอาร์เรย์

หากต้องการเก็บองค์ประกอบหลายรายการ ให้คูณขนาดขององค์ประกอบด้วยจำนวนองค์ประกอบ

malloc(n * sizeof(int)) จะสร้างพื้นที่สำหรับจำนวนเต็ม n ค่า

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int n = 5;
    int *arr = malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) arr[i] = i * i;
    for (int i = 0; i < n; i++) printf("%d ", arr[i]);
    printf("\n");
    free(arr);
    return 0;
}

อาร์เรย์บนฮีปใช้การเข้าถึงผ่านดัชนีของตัวชี้

คุณเข้าถึงอาร์เรย์บนฮีปผ่านตัวชี้ โดยใช้รูปแบบไวยากรณ์ที่คุ้นเคยอย่าง arr[i] ซึ่งเหมือนกับ *(arr + i)

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *arr = malloc(3 * sizeof(int));
    arr[0] = 10;
    *(arr + 1) = 20;
    arr[2] = 30;
    printf("%d %d %d\n", arr[0], arr[1], arr[2]);
    free(arr);
    return 0;
}

การคืนหน่วยความจำ

free(p) คืนบล็อกหน่วยความจำให้ตัวจัดสรร หลังจากนั้นคุณต้องไม่ใช้ p เข้าถึงหน่วยความจำนั้นอีก

ทุกการเรียกใช้ malloc ที่สำเร็จต้องมี free ที่สอดคล้องกัน

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    char *buf = malloc(16);
    if (buf) {
        buf[0] = 'A';
        printf("%c\n", buf[0]);
        free(buf);
    }
    return 0;
}

free(NULL) ปลอดภัย

การเรียกใช้ free กับตัวชี้ NULL จะไม่ทำอะไร และถูกต้องตามกฎของภาษา

วิธีนี้ช่วยให้โค้ดล้างทรัพยากรที่อาจทำงานก่อนการจองสำเร็จเขียนได้ง่ายขึ้น

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = NULL;
    free(p);
    printf("free(NULL) was safe\n");
    return 0;
}

การคืนหน่วยความจำบนฮีป

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

#include <stdio.h>
#include <stdlib.h>

int *make_range(int n) {
    int *a = malloc(n * sizeof(int));
    for (int i = 0; i < n; i++) a[i] = i;
    return a;
}

int main(void) {
    int *r = make_range(4);
    printf("%d %d\n", r[0], r[3]);
    free(r);
    return 0;
}

อย่าแปลงชนิดผลลัพธ์ของ malloc ในภาษา C

ในภาษา C malloc จะคืนค่า void * ซึ่งสามารถแปลงเป็นตัวชี้ชนิดใดก็ได้โดยอัตโนมัติ

การแปลงชนิดจึงไม่จำเป็น และอาจซ่อนปัญหาการลืมเพิ่มไฟล์ส่วนหัว <stdlib.h>

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    long *p = malloc(sizeof(long));
    *p = 1234567L;
    printf("%ld\n", *p);
    free(p);
    return 0;
}

อย่าคืนหน่วยความจำซ้ำสองครั้ง

การเรียกใช้ free กับตัวชี้เดิมสองครั้งถือเป็น พฤติกรรมที่ไม่กำหนด และอาจทำให้ฮีปเสียหาย

กำหนดตัวชี้เป็น NULL หลังคืนหน่วยความจำ เพื่อให้การนำไปใช้ซ้ำโดยไม่ตั้งใจไม่ก่อให้เกิดอันตราย

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int *p = malloc(sizeof(int));
    *p = 1;
    free(p);
    p = NULL;
    free(p);
    printf("no double free\n");
    return 0;
}

ตรวจสอบความเข้าใจ

ทดสอบความรู้เกี่ยวกับ malloc และ free ของคุณ

ทบทวน

คุณได้เรียนรู้พื้นฐานการจองหน่วยความจำบนฮีป:

  • malloc(size) จองไบต์ที่ยังไม่ได้กำหนดค่าเริ่มต้น และคืนค่า NULL หากล้มเหลว
  • ตรวจสอบผลลัพธ์และกำหนดขนาดด้วย sizeof เสมอ
  • free(p) คืนหน่วยความจำ โดยทุกการจองด้วย malloc ต้องมี free หนึ่งครั้ง
  • free(NULL) ปลอดภัย ส่วนการคืนหน่วยความจำซ้ำสองครั้งเป็นพฤติกรรมที่ไม่กำหนด
เริ่มต้นได้ฟรี

เรียนรู้ C ด้วย AI tutor — ฟรี

เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป

คอร์ส
39
บทเรียน
144

คำถามที่พบบ่อย

บทเรียน “malloc และ free” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “malloc และ free” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “malloc และ free”

จัดสรรหน่วยความจำบนฮีป คุณปฏิบัติ C Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “malloc และ free” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C Academy นี้ได้ไหม

ได้ บทเรียน C Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

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

  1. malloc และ free
  2. calloc และ realloc
  3. หน่วยความจำรั่ว
  4. พอยน์เตอร์ลอย
← กลับไปที่ C Academy