Cấp phát bộ nhớ động trong C : Malloc hay Calloc
Cấp phát bộ nhớ động trong C : Malloc vs Calloc
Để cấp phát bộ nhớ động trong C, chúng ta có 2 cách:
void* malloc (size_t size);
void* calloc (size_t num, size_t size);
So sánh
###Sử dụng
- Khi sử dụng
malloc
phải tính toán kích thước vùng nhớ cần cấp phát trước rồi truyền vào chomalloc
- Khi sử dụng
calloc
chỉ cần truyền vào số phần tử và kích thước 1 phần tử, thìcalloc
sẽ tự động tính toán và cấp phát vùng nhớ cần thiết
Ví dụ: Cấp phát mảng 10 phần tử kiểu int:
int *a = (int *) malloc( 10 * sizeof( int ));
int *b = (int *) calloc( 10, sizeof( int ));
Hiệu suất / Perfomance
malloc nhanh hơn so với calloc. Lý do là calloc ngoài việc có nhiệm vụ cấp phát vùng nhớ như malloc, nó còn phải gán giá trị cho tất cả các phần tử của vùng nhớ vừa cấp phát = 0
int *a = (int *) calloc(10, sizeof( int ));
tương đương với
memset(b, 0, 10 * sizeof(int));
Sự an toàn
Sử dụng calloc an toàn hơn malloc vì sau khi khởi tạo vùng nhớ thì calloc sẽ khởi tạo vùng nhớ cấp phát = 0, còn vùng nhớ do malloc cấp phát vẫn chứa giá trị rác nên sẽ dễ gây ra lỗi nếu truy xuất tới vùn nhớ này trước khi gán cho nó một giá trị xác định.
Bài viết hay, nhưng không đồng ý với ý này. Nên sửa lại là chọn
malloc
haycalloc
là do mục tiêu sử dụng. Nếu mình không quan tâm đến giá mặc định của vùng nhớ được cấp thì dùngmalloc
còn nếu muốn tất cả là0
thì dùngcalloc
.Như vậy hợp lý hơn, đưa lựa chọn vào tay người code. Còn nếu viết về sự an toàn thì sẽ đẩy người đọc về phía chọn
calloc
mặc dù không phải lúc nào cũng cần thiết.Góp ý một tí về trình bày, tại sao @Dung_Nguyen lại để thêm một dấu
]
ở đầu một số dòng vậy?em toàn dùng new và delete , dùng lai luôn của C++
Thanks bác Đạt. em mới sửa lại title.
Còn dấu [ là do lúc em replace all trong markdown nó replace lộn chút
hôm trước phỏng vấn VNG nó còn hỏi sự khác nhau giữa malloc với new nữa mà không trả lời được nên mới phải về tìm hiểu lại.
Cái này em cũng chưa biết tại em thấy new thì cú pháp nó gọn, ngắn hơn 2 thằng kia nên dùng lai luôn
New chỉ có trong C++ còn cái này là C mà new phải đi vs realloc chứ
realloc dùng để thay đổi/ xóa vùng nhớ đã được cấp phát còn malloc và calloc dùng để cấp phát vùng nhớ mới.
Tại sao không phải vì calloc phải làm 10 lần công việc của malloc nhỉ? Bạn giải thích cho mình với?
Như bạn thấy thì calloc làm 2 bước:
Nên là nó không thể gấp 10 lần được.
Vậy tại sao bạn lại nghĩ là calloc làm 10 lần công việc của malloc?
Thế mình lấy một ví dụ đơn giản như thế này nhé:
Mình muốn tính tổng từ 1 đến 10.
Mình sẽ có hai hàm như sau:
Như vậy, nếu mình tính tổng từ 1 đến 10 thì mình cần dùng 9 lần hàm
tonghaiso
và 1 lần hàmtong
. Nhưng ở đây nếu không tính đến việc gọi hàm mà chỉ tính đến số phép tính để thực hiện được yêu cầu thì rõ ràng là như nhau đúng không (9 phép tính)?Không phải vì gọi hàm một lần mà nhanh hơn so với gọi 2 hàm khác như bạn đưa ra. Nhỡ đâu ở trong cái phần một hàm ấy, người ta làm rất nhiều việc thì sao? Mà về bản chất ở đây là việc cấp phát bộ nhớ, có thể hình dung bạn có 1 cái bánh mỳ (ở BigC) chẳng hạm, một cái bạn chia thành 10 phần thì bạn phải cắt 9 lần, trong khi cái còn lại thì bạn không phải cắt mà chỉ đánh dấu lên nó 10 vách thôi (hi vọng việc đánh dấu sẽ nhanh hơn việc cắt).
Theo mình thì nên sử dụng calloc vì không nên để giá trị trong biến mà mình không kiểm soát. Tuy nhiên cũng tùy mục đích sử dụng.
calloc
sẽ chậm hơnmalloc
vì nó phải set bộ nhớ = 0.Nếu như bạn muốn lấy 1/2 cái bánh mỳ:
Bạn có thể đề cập đến hàm realloc được không?
anh có thể cho em hỏi là tại sao phải cấp phát cho con trỏ k? nếu k cấp phát thì ảnh hưởng j ?
con trỏ là biến đặc biệt, chỉ trỏ tùm lum, có thể lưu trữ nhiều giá trị (mảng), nên mỗi giá trị phải có 1 cái lổ chứa ==> Phải cấp phát bộ nhớ
Theo mình biết thì đó chỉ là 1 trong 2 công dụng của
realloc
thôi mà?Ngoài tác dụng thay đổi/xóa vùng nhớ đã được cấp phát thì
realloc
còn có thể Tạo mới vùng nhớ đối với những vùng nhớ chưa được khởi tạo mà ?VD: (cấp phát bộ nhớ cho 2 con trỏ a và b)
P/S: Sao bạn không nói đến giải phóng con trỏ
free
(haydelete
) luôn ? (vì mình thấy nó có liên quan đến chủ đề Topic này)Cho em hỏi (int *) là ép kiểu như thế nào vậy ạ?
2 hàm malloc và calloc đều có kiểu
void *
, màvoid *
thì bạn phải ép kiểu cho nó đúng với kiểu dữ liệu của con trỏCho em hỏi nếu mình khai báo như thế này : int* x = (int *)malloc(sizeof(int)); với một biến kiểu int có kích thước 4 bytes thì nó chỉ sử dụng có 4 bytes bộ nhớ đúng không ạ?
Mọi người cho em hỏi về hàm malloc cụ thể của code này:
malloc(1) được cấp phát 1 byte bộ nhớ, kiểu char có kích thước 1 byte. Nhưng em có thể nhập được rất nhiều kí tự: khoảng hơn 200 kí tự. Ai giải thích giúp em với