1、栈内存对齐
#include <iostream>
#include <cstdio>
using std::cout;
int main()
{
char ch1 = 'a';
int i1 = 1;
char ch2 = 'b';
int i2 = 2;
char ch3 = 'c';
int i3 = 3;
char ch4 = 'd';
int i4 = 4;
char ch5 = 'e';
int i5 = 5 ;
char * a = &ch1;
char * b = &ch2;
char * c = &ch3;
char * d = &ch4;
char * e = &ch5;
int * h = &i1;
int * i = &i2;
int * j = &i3;
int * k = &i4;
int * l = &i5;
cout << (void*)a << "\n";
cout << (void*)b << "\n";
cout << (void*)c << "\n";
cout << (void*)d << "\n";
cout << (void*)e << "\n";
cout << (void*)h << "\n";
cout << (void*)i << "\n";
cout << (void*)j << "\n";
cout << (void*)k << "\n";
cout << (void*)l << "\n";
}
编译运行环境:win7 x64 vs2013 编译成32位程序:
运行结果:
0045F917
0045F916
0045F914
0045F915
0045F913
0045F918
0045F924
0045F91C
0045F920
0045F928
编译运行环境:win7 x64 vs2013 编译成64位程序:
运行结果:
000000000016FDB4
000000000016FDB3
000000000016FDB1
000000000016FDB2
000000000016FDB0
000000000016FDB8
000000000016FDC4
000000000016FDBC
000000000016FDC0
000000000016FDC8
编译运行环境:CentOS7.1 x64 gcc 6.1
运行结果:
[chaos@localhost cpp]$ g++ -o 5.2 5.2.cpp
[chaos@localhost cpp]$ ./5.2
0x7ffe7f84639f
0x7ffe7f846397
0x7ffe7f84638f
0x7ffe7f846387
0x7ffe7f84637f
0x7ffe7f846398
0x7ffe7f846390
0x7ffe7f846388
0x7ffe7f846380
0x7ffe7f846378
这个运行结果说明,char*可以按最小粒度为1个字节进行栈分配,不会浪费栈内存。但是如果中间夹杂其他类型的变量,在linux上就可能会形成空隙;但是在windows上vs编译器进行了变量位置的重新排列,最大可能消除空隙。
2、堆内存对齐
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using std::cout;
int _tmain(int argc, _TCHAR* argv[])
{
void * a = malloc(1);
void * b = malloc(2);
void * c = malloc(4);
void * d = malloc(8);
void * e = malloc(10);
cout << a << '\n';
cout << b << '\n';
cout << c << '\n';
cout << d << '\n';
cout << e << '\n';
return 0;
}
编译运行环境:win7 x64 vs2013 编译成32位程序
运行结果:
006195C8
00619608
006195F8
00619658
00619158
编译运行环境:win7 x64 vs2013 编译成64位程序:
运行结果:
0000000000315120
0000000000315130
0000000000315150
00000000003150E0
0000000000319F10
结论:由于windows上的堆分配时x86的堆块头结构_HEAP_ENTRY是8字节,所有32位程序的堆内存总是以8做末尾;而在windows x64上堆块头结构扩展为16字节,所有64位程序的堆内存地址总是以0开头。
编译运行环境:CentOS7.1 x64 gcc 6.1
运行结果:
[chaos@localhost cpp]$ g++ -o 5.2.1 5.2.1.cpp
[chaos@localhost cpp]$ ./5.2.1
0x1f93010
0x1f93030
0x1f93050
0x1f93070
0x1f93090
结论:linux也是以0作为结尾
3.void* 指针由于需要指向其他类型指针,所有在指向其他类型指针后,其限制也被附加到void*指针。所以不再赘述。