Из C языка программирования книга ДЕННИС М. РИТЧИ
Вместо выделения из скомпилированного фиксированного размера array, malloc будет запрашивать пространство у операционной системы по мере необходимости.Поскольку другие действия в программе могут также запрашивать пространство без вызова этого распределителя, пространство, которым управляет malloc , может не быть непрерывным.Таким образом, его свободное хранилище хранится в виде списка свободных блоков .Каждый блок содержит размер , указатель на следующий блок и само пространство .Блоки хранятся в порядке увеличения адреса хранилища, а последний блок (самый высокий адрес) указывает на первый.Блок, возвращаемый функцией malloc (), выглядит следующим образом:
points to
next free
block
|
---------------------------------------
| | size | |
---------------------------------------
| | |..address returned to the user
(ptr-2) (ptr-1) ptr -->
LSB MSB
Здесь
void print_int_heap(unsigned int *ptr, int len) {
printf("PREV_SIZE: [%08x] SIZE: [%08x] MEM: [%08x] for INT malloc(%d)\n", *(ptr-2), *(ptr-1), ptr, len);
}
*(ptr-2)
печатает значение внутри "next free block"
, как показано на рисунке выше, и *(ptr-1)
печатает значение внутри блока "size"
, т. е. сколько памяти выделено, & ptr
печатает адрес, возвращаемый пользователем.Обратите внимание, что здесь ptr
тип равен unsigned int*
, поэтому *(ptr-2)
означает доступ к данным из 2*sizeof(int)
байтов непосредственно перед тем, где ptr
указывает.
А здесь
void print_char_heap(char *ptr, int len){
printf("PREV_SIZE: [%08x] SIZE: [%08x] MEM: [%08x] for CHAR malloc(%d)\n", *(ptr-2), *(ptr-1), ptr, len);
}
при доступе*(ptr-1)
next free
block (ptr-1)--> *(ptr-1) prints data from ? marked location.
| |
---------------------------------------
| | size |? | |
---------------------------------------
| | |..address returned to the user
ptr -->
LSB MSB
* Тип 1050 * равен char*
означает, что при выполнении *(ptr-1)
он будет получать доступ к данным из sizeof(char)
байтов непосредственно перед тем, куда указывает ptr
.
Также лучше использовать valgrind , когда память выделяется динамически и убедитесь, что нет места, где происходит утечка памяти, просто запустив
valgrind --leak-check=full -v ./your_exe
и проанализировав сообщения valgrind
.например, это может показать что-то вроде
==3193== Invalid read of size 4
==3193== at 0x8048459: print_int_heap
==3193== Invalid read of size 4
==3193== at 0x8048461: print_int_heap