#include <stdio.h>
#include <stdlib.h> struct memorypool
{ char infor; int* p;
}; int main()
{ struct memorypool MEMORY_A; MEMORY_A.p = (int*)malloc(10 * sizeof(int)); printf("dia chi cua struct: %p\n", (void *)&MEMORY_A); printf("dia chi cua p trong struct: %p\n", (void *)&MEMORY_A.p); printf("dia chi cua block memory: %p\n", (void *)MEMORY_A.p); free(MEMORY_A.p); return 0;
}
OUTPUT
dia chi cua struct: 0x7fff87d23dc0
dia chi cua p trong struct: 0x7fff87d23dc8
dia chi cua block memory: 0x5598a0c032a0
Tại vì sao ở đây khoảng cách giữa 2 member infor
và *p
lại là 8 byte
trong khi kiểu char
chỉ chiếm 1 byte
.
- Compiler sẽ căng chỉnh (algn) biến trong struct theo kích thước lớn nhất của biến có trong struct . Ở đây là con trỏ có kích thước
8 byte
- Khoảng cách
8 byte
=1 byte char
+7 byte padding
.
Ý tưởng
Memory pool bao gồm 2 khối bộ nhớ:
- Lưu trữ thông tin memory pool
- Trỏ tới vùng nhớ được cấp phát cho memory pool quản li.
#include <stdio.h>
#include <stdlib.h> struct memorypool { char infor; int *p; // sẽ trỏ tới vùng nhớ ngay sau struct
}; int main() { size_t n = 10; // số phần tử muốn chứa // cấp phát: 1 struct + vùng nhớ cho n int void *raw = malloc(sizeof(struct memorypool) + n * sizeof(int)); if (!raw) return -1; // trỏ struct vào đầu struct memorypool *mp = (struct memorypool *)raw; mp->infor = 'A'; // cho p trỏ ngay sau struct mp->p = (int *)(mp + 1); // sử dụng for (size_t i = 0; i < n; i++) { mp->p[i] = i * 10; } printf("Struct addr = %p\n", (void *)mp); printf("Pool addr = %p\n", (void *)mp->p); for (size_t i = 0; i < n; i++) { printf("p[%zu] = %d\n", i, mp->p[i]); } free(raw); return 0;
}
Output
Struct addr = 0x559d8871c2a0
Pool addr = 0x559d8871c2b0
p[0] = 0
p[1] = 10
p[2] = 20
p[3] = 30
p[4] = 40
p[5] = 50
p[6] = 60
p[7] = 70
p[8] = 80
p[9] = 90
Nếu ta lấy 2 địa chỉ trừ cho nhau: pool addr
- struct addr
= 0x559...b0
- 0x559...a0
= 16 byte, đúng với kích thước của struct.
Đây là bước đầu tiên để triển khai memory pool