我在Ubuntu 14.04 VM(Linux 3.13.0-55-generic i686)上进行了一些示例堆栈和堆分配,我对堆分配的内存地址感到困惑。
下面的C代码在堆栈上分配三个32位无符号整数,在堆上分配三个分配大小,32位,16位,最后8位。
在下面的输出中,我们可以看到堆栈上三个32位整数的存储器地址相隔4位。 uint32_t i位于0xbffd4818,后面位于0xbffd481c的4个地址是uint32_t j。所以我们在这里可以看到每个单独的存储器字节都是可寻址的,因此每个4字节存储器块是4个存储器地址。
查看堆分配虽然我们可以看到uint32_t i_ptr指向0x99ae008并且malloc请求了4个字节的空间,所以我希望uint16_t j_ptr从0x99ae00c开始,但它从0x99ae018开始。 uint8_t k_ptr的第三个堆分配在uint16_t i_ptr之后开始16个字节,在uint32_t i_ptr之后也开始16个字节。
C来源:
for k in mieiris['Headword']['Component']:
try:
print(k['Text'])
except KeyError:
pass
except UnicodeEncodeError:
print(unidecode(k['Text']))
CLI输出:
#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;
}
答案 0 :(得分:2)
malloc返回类型为void *
的指针,该指针可以转换为任何其他类型的指针。因此malloc提供了满足任何类型要求的对齐方式。
通常malloc返回一个由段落对齐的地址(在大多数系统中,它等于16个字节)。此外,malloc还分配了段落大小最小的扩展区。所以如果你要写例如
char *p = malloc( 1 );
然后实际上malloc保留了16个字节的范围。