malloc และ free
จัดสรรหน่วยความจำบนฮีป
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 ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- malloc และ free
- calloc และ realloc
- หน่วยความจำรั่ว
- พอยน์เตอร์ลอย