Я делаю несколько примеров размещения стека и кучи на Ubuntu 14.04 VM (Linux 3.13.0-55-generic i686), и я смущен адресами памяти для распределений кучи.В чем разница в адресах этих стеков и кучей памяти?
Приведенный ниже код кода выделяет три 32-разрядных беззнаковых ints в стеке и три распределения в куче уменьшающихся размеров, 32 бита, 16 бит и, наконец, 8 бит.
На выходе ниже мы видим, что адреса памяти для трех 32-битных ints в стеке разделены на 4 бита. uint32_t i находится на 0xbffd4818, а 4 адреса позже на 0xbffd481c - uint32_t j. Таким образом, мы можем видеть, что каждый отдельный байт памяти адресуем, и поэтому каждый 4-байтовый блок памяти имеет 4 адреса памяти.
Глядя на распределения кучи, хотя мы видим, что uint32_t i_ptr указывает на 0x99ae008, а malloc запросил 4 байта пространства, поэтому я ожидал, что uint16_t j_ptr начнется с 0x99ae00c, но начнется с 0x99ae018. Третье распределение кучи для uint8_t k_ptr запускает 16 байт после uint16_t i_ptr, который также запускает 16 байтов после uint32_t i_ptr.
- Является ли это стандартным настройкой ОС по умолчанию, что каждое распределение кучи составляет 16 байт?
- Почему это происходит независимо от размера, который я передал , чтобы malloc?
- Как мы можем поместить 4 байта информации между 0x99ae008 и 0x99ae018?
C Источник:
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
int main() {
register uint32_t ebp asm ("ebp");
printf("0x%x\n", ebp);
register uint32_t esp asm ("esp");
printf("0x%x\n", esp);
uint32_t i;
printf("%p\n", &i);
uint32_t j;
printf("%p\n", &j);
uint32_t k;
printf("%p\n", &k);
uint32_t *i_ptr = malloc(4);
printf("%p\n", i_ptr);
uint16_t *j_ptr = malloc(2);
printf("%p\n", j_ptr);
uint8_t *k_ptr = malloc(1);
printf("%p\n", k_ptr);
free(i_ptr);
free(j_ptr);
free(k_ptr);
return 0;
}
выход CLI:
$ gcc -o heap2 heap2.c
$ ./heap2
0xbffd4838 // EBP
0xbffd4800 // ESP
0xbffd4818 // uint32_t i
0xbffd481c // uint32_t j
0xbffd4820 // uint32_t k
0x99ae008 // uint32_t i_ptr
0x99ae018 // uint16_t j_ptr
0x99ae028 // uint8_t k_ptr
Это объясняет, почему, когда я называю 'malloc (1)' или 'malloc (2)', указатель всегда разделен на 16 бит, как насчет моего вызова 'malloc (4)'? j_ptr только 16 бит в памяти после 32-разрядного распределения (i_ptr)? – jwbensley
malloc не просто выделяет память для использования пользовательским кодом, есть также память, выделенная для поддержки кучи, например: так что free() знает, что делать. – Jasen
@jwbensley Я вижу, что каждая степень выделенной памяти отличается от 16 байт: 0x99ae008 // uint32_t i_ptr 0x99ae018 // uint16_t j_ptr 0x99ae028 –