SlideShare a Scribd company logo
1 of 11
Download to read offline
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 1/11
Cấp phát bộ nhớ động
Trong bài này, bạn sẽ học được cách cấp phát bộ nhớ động trong lập trình C
sử dụng các hàm của thư viện chuẩn  <stdlib.h>.
Con trỏ là một công cụ hữu dụng, mạnh mẽ và linh hoạt mà bạn sẽ dùng
nhiều và rất nhiều lần để giải quyết các bài toán trong lập trình. Cũng
tương tự như vậy, cấp phát bộ nhớ động sẽ không thể khả thi nếu không
có sự hỗ trợ của con trỏ.
Hàm malloc()
malloc() (memory allocation) là hàm đơn giản nhất được sử dụng để cấp
phát bộ nhớ ở thời điểm runtime. Khi bạn sử dụng hàm  malloc() để cấp
phát bộ nhớ, bạn cần phải xác định rõ số byte của bộ nhớ cần cấp phát
trong đối số của hàm. Hàm này sẽ trả về địa chỉ byte đầu tiên của vùng bộ
nhớ được cấp phát nếu cấp phát thành công, hoặc trả về  NULL nếu cấp
phát thất bại. Ví dụ sau mô tả cách cấp phát động 100 byte bộ nhớ với kiểu
int:
int *pointer = (int *) malloc(100);
Nếu được cấp phát thành công, 100 byte bộ nhớ này sẽ nằm trên vùng
heap. Vùng nhớ mới được cấp phát này có thể lưu trữ được tối đa  100/4 =
25 số nguyên (kiểu int 4 byte) hoặc tối đa  100/2 = 50 số nguyên (kiểu int
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 2/11
2 byte). Để tránh khác biệt về kích thước kiểu dữ liệu (ví dụ, kiểu int có thể
là 2 hoặc 4 byte tùy thuộc vào kiến trúc và OS), bạn có thể sử dụng cách
sau:
int *pointer = (int *) malloc(25 * sizeof(int));
Vì hàm  malloc() sẽ trả về một con trỏ có kiểu  void. Con trỏ có kiểu  void
có thể ép được sang bất kỳ kiểu dữ liệu nào. Do đó,  (int *) trong ví dụ
trên được dùng để ép sang kiểu  int. Mặc dù, hiện tại có nhiều trình biên
dịch sẽ tự động ép con trỏ kiểu  void trả về bởi hàm  malloc() sang một
kiểu thích hợp. Tuy nhiên, bạn nên ép sang một kiểu cố định cho chắc chắn.
Hàm calloc()
Cũng như hàm  malloc(), hàm  calloc (contiguous allocation) được dùng
để cấp phát bộ nhớ động. Tuy nhiên, vùng nhớ được cấp phát bởi hàm
calloc() sẽ được set về 0 toàn bộ. Thông thường, hàm  calloc() sẽ
chậm hơn hàm  malloc().
Khi gọi hàm  calloc(), bạn cần cung cấp 2 đối số; một là, số phần tử trong
mảng; hai là, kích thước của mỗi phần tử. Ví dụ bạn cấp phát bộ nhớ cho
một mảng số nguyên gồm 25 phần tử:
int *pointer = (int *) calloc(25, sizeof(int));
Kết quả trả về tương tự hàm  malloc().
Hàm free()
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 3/11
Khác với các biến cục bộ và đối số của một hàm nằm trên vùng nhớ stack
(sẽ được tự động giải phóng ngay sau khi ra khỏi phạm vi của hàm đó),
vùng nhớ được cấp phát động nằm trên vùng heap sẽ không được giải
phóng. Bạn phải tự chịu trách nhiệm cho vùng nhớ mà mình đã cấp phát.
Nếu không giải phóng, chương trình của bạn có thể bị memory leak (tạm
dịch, rò rĩ bộ nhớ). Bạn có thể dùng Valgrind để kiểm tra lỗi này.
Để giải phóng vùng nhớ được cấp phát bởi  malloc() và  calloc(), bạn chỉ
cần gọi hàm  free() với đối số là con trỏ đến phần tử đầu tiên trong vùng
nhớ mà bạn đã cấp phát. Nếu bạn gọi hàm  free() không có đối số, hàm
này sẽ không làm gì cả. Ví dụ, để xóa vùng nhớ đã cấp phát, bạn chỉ cần
gọi:
free(pointer);
Chú ý: bạn không được xóa một vùng nhớ đã cấp phát 2 lần.
Hàm realloc()
Hàm  realloc() (re-allocation) cho phép bạn sử dụng lại vùng nhớ mà bạn
đã cấp phát trước đó bởi hàm  malloc() và  calloc(). Hàm  realloc()
nhận 2 đối số; một là, con trỏ trả về bởi  malloc() hoặc  calloc(); hai là,
số byte cần cấp phát lại. Thông thường, bạn sẽ sử dụng hàm  realloc() để
cấp phát lại trên chính vùng nhớ đã cấp phát trước đó do vùng nhớ cấp
phát trước đó không đủ hoặc quá lớn. Ví dụ cấp phát lại vùng nhớ chứa tối
đa 20 số nguyên:
pointer = (int *) realloc(pointer, 25 * sizeof (int));
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 4/11
Chương trình ví dụ minh họa
Chương trình #1
Xuất ra các phần tử số nguyên đã nhập từ bàn phím, cấp phát động sử
dụng hàm  malloc():
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 5/11
#include <stdio.h>
#include <stdlib.h>
int main()
{
int elems = 0;
int *pointer = NULL;
printf("Enter number of elements: ");
scanf("%d", &elems);
// cap phat bo nho
pointer = (int *) malloc(elems * sizeof(int));
// kiem tra cap phat thanh cong
if (!pointer)
{
printf("Error!");
exit(1);
}
for (int i = 0; i < elems; i++)
{
printf("Enter element %d: ", i + 1);
scanf("%d", pointer + i);
}
printf("Entered array: [");
for (int i = 0; i < elems; i++)
{
printf((i == elems - 1) ? "%d]n" : "%d ", *(pointer + i))
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 6/11
}
free(pointer); // giai phong bo nho
return 0;
}
Khi biên dịch và chạy, bạn có thể nhận được kết quả tương tự như sau:
Enter number of elements: 5
Enter element 1: 1
Enter element 2: 2
Enter element 3: 6
Enter element 4: 7
Enter element 5: 4
Entered array: [1 2 6 7 4]
Chương trình #2
Giống hoàn toàn chương trình trên, ngoại trừ cấp phát động sử dụng hàm
calloc():
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 7/11
#include <stdio.h>
#include <stdlib.h>
int main()
{
int elems = 0;
int *pointer = NULL;
printf("Enter number of elements: ");
scanf("%d", &elems);
// cap phat bo nho
pointer = (int *) calloc(elems, sizeof(int));
// kiem tra cap phat thanh cong
if (!pointer)
{
printf("Error!");
exit(1);
}
for (int i = 0; i < elems; i++)
{
printf("Enter element %d: ", i + 1);
scanf("%d", pointer + i);
}
printf("Entered array: [");
for (int i = 0; i < elems; i++)
{
printf((i == elems - 1) ? "%d]n" : "%d ", *(pointer + i))
4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 8/11
}
free(pointer); // giai phong bo nho
return 0;
}
Kết quả xuất ra giống với chương trình #1.
Chương trình #3
Chương trình minh họa cách sử dụng hàm  realloc():

4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 9/11
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
char *str;
// cap phat bo nho
if (!(str = (char *) calloc(10, sizeof(char))))
{
printf("Error while allocating memory!n");
exit(1);
}
strcpy(str, "laptrinh");
printf("Old string: %sn", str);
// tai cap phat bo nho
if (!(str = (char *) realloc(str, 15)))
{
printf("Error while re-allocating memory!n");
exit(1);
}
strcat(str, "101");
printf("New string: %sn", str);
free(str);
return(0);
}

4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 10/11
Bài trước (https://www.laptrinh101.com/lap-trinh-c/con-tro-pointer/)
Bài sau  (https://www.laptrinh101.com/lap-trinh-c/ham/)
Sau khi biên dịch và chạy, sẽ được kết quả sau:
Old string: laptrinh
New string: laptrinh101
Danh sách bài học (https://www.laptrinh101.com/lap-trinh-c/)
Cập nhật lần cuối vào 14-04-2017 16:21.




4/14/2017 Cấp phát bộ nhớ động
https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 11/11


More Related Content

What's hot

30 bài toán phương pháp tính
30 bài toán phương pháp tính30 bài toán phương pháp tính
30 bài toán phương pháp tínhPham Huy
 
đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )Bui Loi
 
Tom tat cong thuc xstk
Tom tat cong thuc xstkTom tat cong thuc xstk
Tom tat cong thuc xstkBích Anna
 
Xstk 07 12_2015_9914
Xstk 07 12_2015_9914Xstk 07 12_2015_9914
Xstk 07 12_2015_9914Nam Cengroup
 
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư việnThe Nguyen Manh
 
Bài Giảng Đại Số Tuyến Tính - ĐH Thăng Long
Bài Giảng Đại Số Tuyến Tính - ĐH Thăng LongBài Giảng Đại Số Tuyến Tính - ĐH Thăng Long
Bài Giảng Đại Số Tuyến Tính - ĐH Thăng LongHoàng Như Mộc Miên
 
Hệ điều hành (chương 4)
Hệ điều hành (chương 4)Hệ điều hành (chương 4)
Hệ điều hành (chương 4)realpotter
 
Hướng dẫn viết báo cáo chuẩn - HUST
Hướng dẫn viết báo cáo chuẩn - HUSTHướng dẫn viết báo cáo chuẩn - HUST
Hướng dẫn viết báo cáo chuẩn - HUSTThe Nguyen Manh
 
Khong gian vecto (chuong 3)
Khong gian vecto (chuong 3)Khong gian vecto (chuong 3)
Khong gian vecto (chuong 3)Nguyễn Phụng
 
Tính toán khoa học - Chương 4: Giải phương trình phi tuyến
Tính toán khoa học - Chương 4: Giải phương trình phi tuyếnTính toán khoa học - Chương 4: Giải phương trình phi tuyến
Tính toán khoa học - Chương 4: Giải phương trình phi tuyếnChien Dang
 
Trí tuệ nhân tạo "Game cờ Caro"
Trí tuệ nhân tạo "Game cờ Caro"Trí tuệ nhân tạo "Game cờ Caro"
Trí tuệ nhân tạo "Game cờ Caro"Ham Hau
 
Bảng giá trị hàm Laplace
Bảng giá trị hàm LaplaceBảng giá trị hàm Laplace
Bảng giá trị hàm Laplacehiendoanht
 
Bài tập Xác suất thống kê
Bài tập Xác suất thống kêBài tập Xác suất thống kê
Bài tập Xác suất thống kêHọc Huỳnh Bá
 
Công thức truyền tin
Công thức truyền tinCông thức truyền tin
Công thức truyền tinakprovip
 
De xstk k12
De xstk k12De xstk k12
De xstk k12dethinhh
 

What's hot (20)

30 bài toán phương pháp tính
30 bài toán phương pháp tính30 bài toán phương pháp tính
30 bài toán phương pháp tính
 
đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )đại số tuyến tính 2 ( không gian eculid )
đại số tuyến tính 2 ( không gian eculid )
 
Tom tat cong thuc xstk
Tom tat cong thuc xstkTom tat cong thuc xstk
Tom tat cong thuc xstk
 
Xstk 07 12_2015_9914
Xstk 07 12_2015_9914Xstk 07 12_2015_9914
Xstk 07 12_2015_9914
 
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
[Báo cáo] Bài tập lớn Ngôn ngữ lập trình: Quản lý thư viện
 
Bài Giảng Đại Số Tuyến Tính - ĐH Thăng Long
Bài Giảng Đại Số Tuyến Tính - ĐH Thăng LongBài Giảng Đại Số Tuyến Tính - ĐH Thăng Long
Bài Giảng Đại Số Tuyến Tính - ĐH Thăng Long
 
Hệ điều hành (chương 4)
Hệ điều hành (chương 4)Hệ điều hành (chương 4)
Hệ điều hành (chương 4)
 
Hướng dẫn viết báo cáo chuẩn - HUST
Hướng dẫn viết báo cáo chuẩn - HUSTHướng dẫn viết báo cáo chuẩn - HUST
Hướng dẫn viết báo cáo chuẩn - HUST
 
2. Bài Tập Các Phép Toán Trên Ma Trận
2. Bài Tập Các Phép Toán Trên Ma Trận2. Bài Tập Các Phép Toán Trên Ma Trận
2. Bài Tập Các Phép Toán Trên Ma Trận
 
Đề tài: Biên soạn tập bài giảng môn xác suất thống kê Trường ĐH
Đề tài: Biên soạn tập bài giảng môn xác suất thống kê Trường ĐHĐề tài: Biên soạn tập bài giảng môn xác suất thống kê Trường ĐH
Đề tài: Biên soạn tập bài giảng môn xác suất thống kê Trường ĐH
 
Hop ngu mips
Hop ngu mipsHop ngu mips
Hop ngu mips
 
Khong gian vecto (chuong 3)
Khong gian vecto (chuong 3)Khong gian vecto (chuong 3)
Khong gian vecto (chuong 3)
 
Tính toán khoa học - Chương 4: Giải phương trình phi tuyến
Tính toán khoa học - Chương 4: Giải phương trình phi tuyếnTính toán khoa học - Chương 4: Giải phương trình phi tuyến
Tính toán khoa học - Chương 4: Giải phương trình phi tuyến
 
Hệ thống thông tin
Hệ thống thông tinHệ thống thông tin
Hệ thống thông tin
 
Trí tuệ nhân tạo "Game cờ Caro"
Trí tuệ nhân tạo "Game cờ Caro"Trí tuệ nhân tạo "Game cờ Caro"
Trí tuệ nhân tạo "Game cờ Caro"
 
Bảng giá trị hàm Laplace
Bảng giá trị hàm LaplaceBảng giá trị hàm Laplace
Bảng giá trị hàm Laplace
 
Bài tập Xác suất thống kê
Bài tập Xác suất thống kêBài tập Xác suất thống kê
Bài tập Xác suất thống kê
 
Công thức truyền tin
Công thức truyền tinCông thức truyền tin
Công thức truyền tin
 
Kỹ thuật số
Kỹ thuật sốKỹ thuật số
Kỹ thuật số
 
De xstk k12
De xstk k12De xstk k12
De xstk k12
 

Similar to Cấp phát bộ nhớ động trong C

Bài tập mẫu C và C++ có giải
Bài tập mẫu C và C++ có giảiBài tập mẫu C và C++ có giải
Bài tập mẫu C và C++ có giảiTrung Thanh Nguyen
 
Giao trinh bai tap c va c++
Giao trinh bai tap c va c++Giao trinh bai tap c va c++
Giao trinh bai tap c va c++Congdat Le
 
Hàm và Chuỗi
Hàm và ChuỗiHàm và Chuỗi
Hàm và Chuỗipnanhvn
 
Buffer overflow(bao cao)
Buffer overflow(bao cao)Buffer overflow(bao cao)
Buffer overflow(bao cao)phanleson
 
Lập Trình an toàn - Secure programming
Lập Trình an toàn - Secure programmingLập Trình an toàn - Secure programming
Lập Trình an toàn - Secure programmingbeatmaking
 
Cq lt hdt-th2011-02-tuan04
Cq lt hdt-th2011-02-tuan04Cq lt hdt-th2011-02-tuan04
Cq lt hdt-th2011-02-tuan04. .
 
Nmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_inNmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_inHuy Nguyễn
 
Lập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiểnLập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiểnMr Giap
 
Stl vector nguyen_trihai_11520094_khmt06
Stl vector nguyen_trihai_11520094_khmt06Stl vector nguyen_trihai_11520094_khmt06
Stl vector nguyen_trihai_11520094_khmt06Quach Long
 
lap trinh c Phan2 chuong5
 lap trinh c Phan2 chuong5 lap trinh c Phan2 chuong5
lap trinh c Phan2 chuong5thanhyu
 

Similar to Cấp phát bộ nhớ động trong C (20)

Bài tập mẫu C và C++ có giải
Bài tập mẫu C và C++ có giảiBài tập mẫu C và C++ có giải
Bài tập mẫu C và C++ có giải
 
Giao trinh bai tap c va c++
Giao trinh bai tap c va c++Giao trinh bai tap c va c++
Giao trinh bai tap c va c++
 
Giao trinh bai tap c va c++
Giao trinh bai tap c va c++Giao trinh bai tap c va c++
Giao trinh bai tap c va c++
 
Ctdl lab01
Ctdl lab01Ctdl lab01
Ctdl lab01
 
Basic C programming
Basic C programmingBasic C programming
Basic C programming
 
Hàm và Chuỗi
Hàm và ChuỗiHàm và Chuỗi
Hàm và Chuỗi
 
Buffer overflow(bao cao)
Buffer overflow(bao cao)Buffer overflow(bao cao)
Buffer overflow(bao cao)
 
Lập Trình an toàn - Secure programming
Lập Trình an toàn - Secure programmingLập Trình an toàn - Secure programming
Lập Trình an toàn - Secure programming
 
C đến C++ phần 1
C đến C++ phần 1C đến C++ phần 1
C đến C++ phần 1
 
Cq lt hdt-th2011-02-tuan04
Cq lt hdt-th2011-02-tuan04Cq lt hdt-th2011-02-tuan04
Cq lt hdt-th2011-02-tuan04
 
Nmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_inNmlt c12 quan_lybonho_in
Nmlt c12 quan_lybonho_in
 
Nmlt c12 quan_lybonho
Nmlt c12 quan_lybonhoNmlt c12 quan_lybonho
Nmlt c12 quan_lybonho
 
Lập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiểnLập trình C cơ bản cho vi điều khiển
Lập trình C cơ bản cho vi điều khiển
 
C9 templates
C9 templatesC9 templates
C9 templates
 
C9 templates
C9 templatesC9 templates
C9 templates
 
Stl vector nguyen_trihai_11520094_khmt06
Stl vector nguyen_trihai_11520094_khmt06Stl vector nguyen_trihai_11520094_khmt06
Stl vector nguyen_trihai_11520094_khmt06
 
lap trinh c Phan2 chuong5
 lap trinh c Phan2 chuong5 lap trinh c Phan2 chuong5
lap trinh c Phan2 chuong5
 
Chuong5 (2)
Chuong5 (2)Chuong5 (2)
Chuong5 (2)
 
Bai 18
Bai 18Bai 18
Bai 18
 
T4
T4T4
T4
 

Cấp phát bộ nhớ động trong C

  • 1. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 1/11 Cấp phát bộ nhớ động Trong bài này, bạn sẽ học được cách cấp phát bộ nhớ động trong lập trình C sử dụng các hàm của thư viện chuẩn  <stdlib.h>. Con trỏ là một công cụ hữu dụng, mạnh mẽ và linh hoạt mà bạn sẽ dùng nhiều và rất nhiều lần để giải quyết các bài toán trong lập trình. Cũng tương tự như vậy, cấp phát bộ nhớ động sẽ không thể khả thi nếu không có sự hỗ trợ của con trỏ. Hàm malloc() malloc() (memory allocation) là hàm đơn giản nhất được sử dụng để cấp phát bộ nhớ ở thời điểm runtime. Khi bạn sử dụng hàm  malloc() để cấp phát bộ nhớ, bạn cần phải xác định rõ số byte của bộ nhớ cần cấp phát trong đối số của hàm. Hàm này sẽ trả về địa chỉ byte đầu tiên của vùng bộ nhớ được cấp phát nếu cấp phát thành công, hoặc trả về  NULL nếu cấp phát thất bại. Ví dụ sau mô tả cách cấp phát động 100 byte bộ nhớ với kiểu int: int *pointer = (int *) malloc(100); Nếu được cấp phát thành công, 100 byte bộ nhớ này sẽ nằm trên vùng heap. Vùng nhớ mới được cấp phát này có thể lưu trữ được tối đa  100/4 = 25 số nguyên (kiểu int 4 byte) hoặc tối đa  100/2 = 50 số nguyên (kiểu int
  • 2. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 2/11 2 byte). Để tránh khác biệt về kích thước kiểu dữ liệu (ví dụ, kiểu int có thể là 2 hoặc 4 byte tùy thuộc vào kiến trúc và OS), bạn có thể sử dụng cách sau: int *pointer = (int *) malloc(25 * sizeof(int)); Vì hàm  malloc() sẽ trả về một con trỏ có kiểu  void. Con trỏ có kiểu  void có thể ép được sang bất kỳ kiểu dữ liệu nào. Do đó,  (int *) trong ví dụ trên được dùng để ép sang kiểu  int. Mặc dù, hiện tại có nhiều trình biên dịch sẽ tự động ép con trỏ kiểu  void trả về bởi hàm  malloc() sang một kiểu thích hợp. Tuy nhiên, bạn nên ép sang một kiểu cố định cho chắc chắn. Hàm calloc() Cũng như hàm  malloc(), hàm  calloc (contiguous allocation) được dùng để cấp phát bộ nhớ động. Tuy nhiên, vùng nhớ được cấp phát bởi hàm calloc() sẽ được set về 0 toàn bộ. Thông thường, hàm  calloc() sẽ chậm hơn hàm  malloc(). Khi gọi hàm  calloc(), bạn cần cung cấp 2 đối số; một là, số phần tử trong mảng; hai là, kích thước của mỗi phần tử. Ví dụ bạn cấp phát bộ nhớ cho một mảng số nguyên gồm 25 phần tử: int *pointer = (int *) calloc(25, sizeof(int)); Kết quả trả về tương tự hàm  malloc(). Hàm free()
  • 3. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 3/11 Khác với các biến cục bộ và đối số của một hàm nằm trên vùng nhớ stack (sẽ được tự động giải phóng ngay sau khi ra khỏi phạm vi của hàm đó), vùng nhớ được cấp phát động nằm trên vùng heap sẽ không được giải phóng. Bạn phải tự chịu trách nhiệm cho vùng nhớ mà mình đã cấp phát. Nếu không giải phóng, chương trình của bạn có thể bị memory leak (tạm dịch, rò rĩ bộ nhớ). Bạn có thể dùng Valgrind để kiểm tra lỗi này. Để giải phóng vùng nhớ được cấp phát bởi  malloc() và  calloc(), bạn chỉ cần gọi hàm  free() với đối số là con trỏ đến phần tử đầu tiên trong vùng nhớ mà bạn đã cấp phát. Nếu bạn gọi hàm  free() không có đối số, hàm này sẽ không làm gì cả. Ví dụ, để xóa vùng nhớ đã cấp phát, bạn chỉ cần gọi: free(pointer); Chú ý: bạn không được xóa một vùng nhớ đã cấp phát 2 lần. Hàm realloc() Hàm  realloc() (re-allocation) cho phép bạn sử dụng lại vùng nhớ mà bạn đã cấp phát trước đó bởi hàm  malloc() và  calloc(). Hàm  realloc() nhận 2 đối số; một là, con trỏ trả về bởi  malloc() hoặc  calloc(); hai là, số byte cần cấp phát lại. Thông thường, bạn sẽ sử dụng hàm  realloc() để cấp phát lại trên chính vùng nhớ đã cấp phát trước đó do vùng nhớ cấp phát trước đó không đủ hoặc quá lớn. Ví dụ cấp phát lại vùng nhớ chứa tối đa 20 số nguyên: pointer = (int *) realloc(pointer, 25 * sizeof (int));
  • 4. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 4/11 Chương trình ví dụ minh họa Chương trình #1 Xuất ra các phần tử số nguyên đã nhập từ bàn phím, cấp phát động sử dụng hàm  malloc():
  • 5. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 5/11 #include <stdio.h> #include <stdlib.h> int main() { int elems = 0; int *pointer = NULL; printf("Enter number of elements: "); scanf("%d", &elems); // cap phat bo nho pointer = (int *) malloc(elems * sizeof(int)); // kiem tra cap phat thanh cong if (!pointer) { printf("Error!"); exit(1); } for (int i = 0; i < elems; i++) { printf("Enter element %d: ", i + 1); scanf("%d", pointer + i); } printf("Entered array: ["); for (int i = 0; i < elems; i++) { printf((i == elems - 1) ? "%d]n" : "%d ", *(pointer + i))
  • 6. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 6/11 } free(pointer); // giai phong bo nho return 0; } Khi biên dịch và chạy, bạn có thể nhận được kết quả tương tự như sau: Enter number of elements: 5 Enter element 1: 1 Enter element 2: 2 Enter element 3: 6 Enter element 4: 7 Enter element 5: 4 Entered array: [1 2 6 7 4] Chương trình #2 Giống hoàn toàn chương trình trên, ngoại trừ cấp phát động sử dụng hàm calloc():
  • 7. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 7/11 #include <stdio.h> #include <stdlib.h> int main() { int elems = 0; int *pointer = NULL; printf("Enter number of elements: "); scanf("%d", &elems); // cap phat bo nho pointer = (int *) calloc(elems, sizeof(int)); // kiem tra cap phat thanh cong if (!pointer) { printf("Error!"); exit(1); } for (int i = 0; i < elems; i++) { printf("Enter element %d: ", i + 1); scanf("%d", pointer + i); } printf("Entered array: ["); for (int i = 0; i < elems; i++) { printf((i == elems - 1) ? "%d]n" : "%d ", *(pointer + i))
  • 8. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 8/11 } free(pointer); // giai phong bo nho return 0; } Kết quả xuất ra giống với chương trình #1. Chương trình #3 Chương trình minh họa cách sử dụng hàm  realloc(): 
  • 9. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 9/11 #include <stdio.h> #include <string.h> #include <stdlib.h> int main() { char *str; // cap phat bo nho if (!(str = (char *) calloc(10, sizeof(char)))) { printf("Error while allocating memory!n"); exit(1); } strcpy(str, "laptrinh"); printf("Old string: %sn", str); // tai cap phat bo nho if (!(str = (char *) realloc(str, 15))) { printf("Error while re-allocating memory!n"); exit(1); } strcat(str, "101"); printf("New string: %sn", str); free(str); return(0); } 
  • 10. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 10/11 Bài trước (https://www.laptrinh101.com/lap-trinh-c/con-tro-pointer/) Bài sau  (https://www.laptrinh101.com/lap-trinh-c/ham/) Sau khi biên dịch và chạy, sẽ được kết quả sau: Old string: laptrinh New string: laptrinh101 Danh sách bài học (https://www.laptrinh101.com/lap-trinh-c/) Cập nhật lần cuối vào 14-04-2017 16:21.    
  • 11. 4/14/2017 Cấp phát bộ nhớ động https://www.laptrinh101.com/lap-trinh-c/cap-phat-bo-nho-dong/ 11/11 