~~~~ 无聊写了一个小测试,在windows下使用vs编译,和gcc编译的C++程序,内存地址分配上会有什么差异,还有和linux上gcc编译的差异。
先附上代码,外加结果:
#include <string>
#include <stdio.h>
#include <stdlib.h>
void printf_test_address(int* _val, const char* tag) {
printf("%s: _val[0] = %x, _val[1] = %x, _val[2] = %x.\n", tag, _val[0], _val[1], _val[2]);
}
int main() {
char* p1 = NULL, *p2 = NULL, *p3 = NULL, *p4 = NULL;
char* p5 = NULL, *p6 = NULL, *p7 = NULL, *p8 = NULL;
printf(" ----------------------------test1---------------------\n");
printf("p1 = %p, p2 = %p, &p1 = %p, &p2 = %p.\n", p1, p2, &p1, &p2);
printf("p3 = %p, p4 = %p, &p3 = %p, &p4 = %p.\n", p3, p4, &p3, &p4);
printf("p5 = %p, p6 = %p, &p5 = %p, &p6 = %p.\n", p5, p6, &p5, &p6);
printf("p7 = %p, p8 = %p, &p7 = %p, &p8 = %p.\n", p7, p8, &p7, &p8);
p1 = new char[20];
p2 = new char[20];
p3 = new char[20];
p4 = new char[20];
printf("p1 = %p, p2 = %p, &p1 = %p, &p2 = %p.\n", p1, p2, &p1, &p2);
printf("p3 = %p, p4 = %p, &p3 = %p, &p4 = %p.\n", p3, p4, &p3, &p4);
p5 = (char*)malloc(sizeof(char) * 20);
p6 = (char*)malloc(sizeof(char) * 20);
p7 = (char*)malloc(sizeof(char) * 20);
p8 = (char*)malloc(sizeof(char) * 20);
printf("p5 = %p, p6 = %p, &p5 = %p, &p6 = %p.\n", p5, p6, &p5, &p6);
printf("p7 = %p, p8 = %p, &p7 = %p, &p8 = %p.\n", p7, p8, &p7, &p8);
printf("&p1 - &p2 = %d, &p2 - &p3 = %d, &p3 - &p4 = %d.\n",
(long)(&p1) - (long)(&p2), (long)(&p2) - (long)(&p3), (long)(&p3) - (long)(&p4));
printf("&p5 - &p6 = %d, &p6 - &p7 = %d, &p7 - &p8 = %d.\n",
(long)(&p5) - (long)(&p6), (long)(&p6) - (long)(&p7), (long)(&p7) - (long)(&p8));
printf("p1 - p2 = %d, p2 - p3 = %d, p3 - p4 = %d.\n",
(long)(p1) - (long)(p2), (long)(p2) - (long)(p3), (long)(p3) - (long)(p4));
printf("p5 - p6 = %d, p6 - p7 = %d, p7 - p8 = %d.\n",
(long)(p5) - (long)(p6), (long)(p6) - (long)(p7), (long)(p7) - (long)(p8));
printf_test_address((int*)&p1, "p1");
printf_test_address((int*)&p2, "p2");
printf_test_address((int*)&p3, "p3");
printf_test_address((int*)&p4, "p4");
printf_test_address((int*)&p5, "p5");
printf_test_address((int*)&p6, "p6");
printf_test_address((int*)&p7, "p7");
printf_test_address((int*)&p8, "p8");
if (p1) {
delete p1;
p1 = NULL;
}
if (p2) {
delete p2;
p2 = NULL;
}
if (p3) {
delete p3;
p3 = NULL;
}
if (p4) {
delete p4;
p4 = NULL;
}
if (p5) {
free(p5);
p5 = NULL;
}
if (p6) {
free(p6);
p6 = NULL;
}
if (p7) {
free(p7);
p7 = NULL;
}
if (p8) {
free(p8);
p8 = NULL;
}
printf(" ----------------------------test2--------------------- \n");
p1 = new char[20];
p2 = p1;
p3 = new char[20];
p4 = p3;
printf("p1 = %p, p2 = %p, &p1 = %p, &p2 = %p.\n", p1, p2, &p1, &p2);
printf("p3 = %p, p4 = %p, &p3 = %p, &p4 = %p.\n", p3, p4, &p3, &p4);
p5 = (char*)malloc(sizeof(char) * 20);
p6 = p5;
p7 = (char*)malloc(sizeof(char) * 20);
p8 = p7;
printf("p5 = %p, p6 = %p, &p5 = %p, &p6 = %p.\n", p5, p6, &p5, &p6);
printf("p7 = %p, p8 = %p, &p7 = %p, &p8 = %p.\n", p7, p8, &p7, &p8);
printf("p2[0] = %d, p2[10] = %d, p2[20] = %d, p2[30] = %d.\n", p2[0], p2[10], p2[20], p2[30]);
printf("p4[0] = %d, p4[10] = %d, p4[20] = %d, p4[30] = %d.\n", p4[0], p4[10], p4[20], p4[30]);
printf("p6[0] = %d, p6[10] = %d, p6[20] = %d, p6[30] = %d.\n", p6[0], p6[10], p6[20], p6[30]);
printf("p7[0] = %d, p7[10] = %d, p7[20] = %d, p7[30] = %d.\n", p7[0], p7[10], p7[20], p7[30]);
if (p1) {
delete p1;
p1 = NULL;
}
if (p3) {
delete p3;
p3 = NULL;
}
if (p5) {
free(p5);
p5 = NULL;
}
if (p8) {
free(p8);
p8 = NULL;
}
printf("delete -------------------------------------------------\n");
printf("p2[0] = %d, p2[10] = %d, p2[20] = %d, p2[30] = %d.\n", p2[0], p2[10], p2[20], p2[30]);
printf("p4[0] = %d, p4[10] = %d, p4[20] = %d, p4[30] = %d.\n", p4[0], p4[10], p4[20], p4[30]);
printf("p6[0] = %d, p6[10] = %d, p6[20] = %d, p6[30] = %d.\n", p6[0], p6[10], p6[20], p6[30]);
printf("p7[0] = %d, p7[10] = %d, p7[20] = %d, p7[30] = %d.\n", p7[0], p7[10], p7[20], p7[30]);
//这个句话在控制台上运行可有可无,直接运行用来暂停
getchar();
return 0;
}
下面是结果,大家比较一下结果,就会发现一些不同之处,这里全部跑32位,不跑64位。
第一个windows上vs编译的结果:注意这是x86,debug版本
第二个windows上gcc编译的结果:
编译的指令:gcc -o test main.cpp -lstdc++
第三个ubuntu16.04上gcc编译的结果:
编译语句: gcc -o test main.cpp -lstdc++ -m32
很明显,我们可以看出来,在vs上编译的程序,变量初始化的内存不是连续的,连后面连续申请的内存,也不一定是连续的,同时在windows上不同编译器,他们的对齐长度不一,感觉上是有内存浪费,中间有一些内存没有使用;然后比较linux和windows系统,我们可以发现linux上,申请内存的对齐长度只有24,而windows是32。