01/10/2018, 10:44

Đảo lộn thứ tự tham số truyền vào hàm calloc có làm sao ko?

Chào mọi người! Mình khá thắc mắc khi làm việc với calloc, có 1 lần mình nhập nhầm int *a=(int *)calloc(sizeof(int),1); mà dường như chương trình vẫn chạy bình thường. Mà trong khi đó mình nghĩ nếu như kia thì sẽ cấp cho 4 ô nhớ, mỗi ô 1 byte, vậy làm sao có thể chứa được 1 giá trị 0 trong mỗi ô nhớ đó nhỉ? Vậy là nó sẽ tràn sang các ô nhớ bên cạnh nó để lưu trữ hay như nào vậy mọi người?

Phạm Minh Anh Hữu viết 12:49 ngày 01/10/2018

Prototype: void* calloc (size_t num, size_t size);
Tham số truyền vào là khác nhau chứ bạn, trường hợp trên của bạn là may, vì

 *a=(int *)calloc(sizeof(int), 1);

so với

 *a=(int *)calloc(1, sizeof(int));

là giống nhau, nó đều cấp phát 4 bytes cho con trỏ a. Theo cách bạn làm nhầm ấy thì nó cấp thêm 4 blocks mỗi block là 1 byte, còn theo cách đúng là nó cấp cho ta 1 block 4 bytes luôn. Còn nếu bạn thay lại là *a=(int *)calloc(2, sizeof(int)); chẳng hạn thì mọi thứ khác rồi, nó cấp cho ta 2 blocks mỗi block 4 byte.

Theo mình là như vậy

rogp10 viết 12:47 ngày 01/10/2018

Không khác gì nhau đâu vấn đề là sai ý nghĩa thôi, vì calloc luôn align theo 8/16 byte.

Nguyễn Quang Khải viết 12:58 ngày 01/10/2018

ah, ra là calloc align theo 8/16 byte à, giờ mình mới biết thank b nhé!

Nguyễn Quang Khải viết 12:58 ngày 01/10/2018

Uh mình cũng biết, nhưng mình code thử tìm cách để cho ctrinh lỗi mà ko được, lần nào cũng chạy đúng. Chắc do bạn kia nói, calloc luôn align theo 8 hoặc 16 byte nên việc cấp phát 4,1 hay 1,4 ở trên ko có lỗi gì xảy ra

rogp10 viết 12:51 ngày 01/10/2018

Đúng vậy. n slot * m byte hay m slot * n byte chỉ quan trọng khi align theo số byte, mà calloc có alignment cố định.

Nhưng dù gì cũng không nên viết ngược như vậy.

Phạm Minh Anh Hữu viết 12:51 ngày 01/10/2018

Bạn có thể nói rõ hơn cái khoản alignment của calloc không 8/16 bytes là sao ạ?

rogp10 viết 12:52 ngày 01/10/2018

Một địa chỉ gọi là (2, 4, 8, 16) byte aligned thì phải chia hết cho 2, 4, 8 hoặc 16. Để đạt được alignment C buộc sizeof() cũng phải chia hết như vậy, vì vậy sizeof() đã có alignment riêng.

Phạm Minh Anh Hữu viết 12:53 ngày 01/10/2018

*a=(char *)calloc(7, sizeof(char)); vậy như thế này thì size cấp phát trên 32bit là 8 bytes hả ?

rogp10 viết 12:51 ngày 01/10/2018

Calloc có 3 bảo đảm:

  • Đủ số bytes cho bạn, hoặc trả về NULL
  • Địa chỉ aligned
  • Các byte đều là 0

còn thực sự là mấy byte thì cũng khó, nhưng có thể là 8 bytes + overhead.

Lưu ý: Alignment của calloc là cố định cho từng compiler, vì vậy viết ngược rất nguy hiểm.

Bài liên quan
0