SlideShare a Scribd company logo
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

Các toán tử trong c
Các toán tử trong cCác toán tử trong c
Các toán tử trong c
Iam Me
 
De thi quan_tri_san_xuat_dich_vu
De thi quan_tri_san_xuat_dich_vuDe thi quan_tri_san_xuat_dich_vu
De thi quan_tri_san_xuat_dich_vu
trinhhoahong
 
Bao cao de tai thi trac nghiem tieng anh
Bao cao de tai thi trac nghiem tieng anhBao cao de tai thi trac nghiem tieng anh
Bao cao de tai thi trac nghiem tieng anh
Kết Vẻ
 
Nhập môn công nghệ thông tin
Nhập môn công nghệ thông tinNhập môn công nghệ thông tin
Nhập môn công nghệ thông tin
Thanh Lee
 
BÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPT
BÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPTBÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPT
BÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPT
MasterCode.vn
 
Giáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhất
Giáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhấtGiáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhất
Giáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhất
Trung tâm Advance Cad
 
Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)lieu_lamlam
 
Bài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPT
Bài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPTBài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPT
Bài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPT
MasterCode.vn
 
Bai tap va loi giai sql
Bai tap va loi giai sqlBai tap va loi giai sql
Bai tap va loi giai sql. .
 
Đồ Thị Matlab
Đồ Thị Matlab Đồ Thị Matlab
Đồ Thị Matlab
JoneCole
 
Xây dựng hệ thống hỗ trợ thi trắc nghiệm
Xây dựng hệ thống hỗ trợ thi trắc nghiệmXây dựng hệ thống hỗ trợ thi trắc nghiệm
Xây dựng hệ thống hỗ trợ thi trắc nghiệmVcoi Vit
 
Học python
Học pythonHọc python
Học python
Tung Nguyen Xuan
 
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
MasterCode.vn
 
Giáo trình Lập trình C căn bản - Aptech
Giáo trình Lập trình C căn bản - AptechGiáo trình Lập trình C căn bản - Aptech
Giáo trình Lập trình C căn bản - AptechMasterCode.vn
 
[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...
[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...
[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...
The Nguyen Manh
 
Bài giảng Công Nghệ Phần Mềm
Bài giảng Công Nghệ Phần MềmBài giảng Công Nghệ Phần Mềm
Bài giảng Công Nghệ Phần Mềm
Hoài Phạm
 
Kiến thức cơ bản về lập trình hợp ngữ Assembly
Kiến thức cơ bản về lập trình hợp ngữ AssemblyKiến thức cơ bản về lập trình hợp ngữ Assembly
Kiến thức cơ bản về lập trình hợp ngữ Assembly
tTrngMnh
 
[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam
[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam
[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam
Tran Van Cuong
 
Tai lieu lap trinh shell linux unix
Tai lieu lap trinh shell linux   unixTai lieu lap trinh shell linux   unix
Tai lieu lap trinh shell linux unix
kaivnit
 

What's hot (20)

Các toán tử trong c
Các toán tử trong cCác toán tử trong c
Các toán tử trong c
 
De thi quan_tri_san_xuat_dich_vu
De thi quan_tri_san_xuat_dich_vuDe thi quan_tri_san_xuat_dich_vu
De thi quan_tri_san_xuat_dich_vu
 
Bao cao de tai thi trac nghiem tieng anh
Bao cao de tai thi trac nghiem tieng anhBao cao de tai thi trac nghiem tieng anh
Bao cao de tai thi trac nghiem tieng anh
 
Nhập môn công nghệ thông tin
Nhập môn công nghệ thông tinNhập môn công nghệ thông tin
Nhập môn công nghệ thông tin
 
BÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPT
BÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPTBÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPT
BÀI 5 Tổ chức hình vẽ với Layer & Làm việc với Symbol - Giáo trình FPT
 
Giáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhất
Giáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhấtGiáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhất
Giáo trình lắp ráp và xuất bản vẽ Solidworks 2016 hay nhất
 
Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)Bo de toan roi rac (on thi cao hoc khmt)
Bo de toan roi rac (on thi cao hoc khmt)
 
Bài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPT
Bài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPTBài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPT
Bài 6: Thiết kế cơ sở dữ liệu - Giáo trình FPT
 
Bai tap va loi giai sql
Bai tap va loi giai sqlBai tap va loi giai sql
Bai tap va loi giai sql
 
Đồ Thị Matlab
Đồ Thị Matlab Đồ Thị Matlab
Đồ Thị Matlab
 
Xây dựng hệ thống hỗ trợ thi trắc nghiệm
Xây dựng hệ thống hỗ trợ thi trắc nghiệmXây dựng hệ thống hỗ trợ thi trắc nghiệm
Xây dựng hệ thống hỗ trợ thi trắc nghiệm
 
Học python
Học pythonHọc python
Học python
 
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
Bài 4: NGÔN NGỮ TRUY VẤN CÓ CẤU TRÚC (SQL)
 
Giáo trình Lập trình C căn bản - Aptech
Giáo trình Lập trình C căn bản - AptechGiáo trình Lập trình C căn bản - Aptech
Giáo trình Lập trình C căn bản - Aptech
 
[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...
[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...
[Báo cáo] Bài tập lớn Kỹ thuật phần mềm ứng dụng: Thiết kế hệ thống quản lý p...
 
Bài giảng Công Nghệ Phần Mềm
Bài giảng Công Nghệ Phần MềmBài giảng Công Nghệ Phần Mềm
Bài giảng Công Nghệ Phần Mềm
 
Kiến thức cơ bản về lập trình hợp ngữ Assembly
Kiến thức cơ bản về lập trình hợp ngữ AssemblyKiến thức cơ bản về lập trình hợp ngữ Assembly
Kiến thức cơ bản về lập trình hợp ngữ Assembly
 
Baigiang05 thuattoan(1s 1p)
Baigiang05 thuattoan(1s 1p)Baigiang05 thuattoan(1s 1p)
Baigiang05 thuattoan(1s 1p)
 
[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam
[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam
[14HCB-PTTKHTTT]- Quản Lý Siêu Thị Điện Thoại Phương Nam
 
Tai lieu lap trinh shell linux unix
Tai lieu lap trinh shell linux   unixTai lieu lap trinh shell linux   unix
Tai lieu lap trinh shell linux unix
 

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ải
Trung 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
 
Basic C programming
Basic C programmingBasic C programming
Basic C programming
TechMaster Vietnam
 
Hàm và Chuỗi
Hàm và ChuỗiHàm và Chuỗi
Hàm và Chuỗi
pnanhvn
 
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 programming
beatmaking
 
C đến C++ phần 1
C đến C++ phần 1C đến C++ phần 1
C đến C++ phần 1
TechMaster Vietnam
 
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
Huy Nguyễn
 
Nmlt c12 quan_lybonho
Nmlt c12 quan_lybonhoNmlt c12 quan_lybonho
Nmlt c12 quan_lybonho
Minh Ngoc Tran
 
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
Mr Giap
 
C9 templates
C9 templatesC9 templates
C9 templates
Tiến Quang Phan
 
Stl vector nguyen_trihai_11520094_khmt06
Stl vector nguyen_trihai_11520094_khmt06Stl vector nguyen_trihai_11520094_khmt06
Stl vector nguyen_trihai_11520094_khmt06
Quach 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 