C/C++编译器会把代码直接分为四个小区:
(1).栈区(stack):由编译器自动分配和释放,存放函数的参数值,局部变量的值等。
(2).堆区(heap):一般是由程序员分配释放(动态内存申请与释放),若程序员不释放,程序结束时可能由操作系统回收
(3).全局区(静态区,常量区):全局变量和静态变量的存储是放在一起的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域,该区域在程序结束后由操作系统释放。常量区是字符串常量和其他常量的存储位置,程序结束后由系统自动释放。
(4).程序代码区:存放函数体的二进制代码。
下面来看看具体实例:
char* GetCharInfo1()
{
char *p1 = "abcdef";
return p1;
}
char* GetCharInfo2()
{
char *p2 = "abcd";
return p2;
}
int main()
{
char* pA = GetCharInfo1();
char* pB = GetCharInfo2();
//输出p1, p2指向内存空间的数据
printf("pA:%s, pB:%s\n", pA, pB);
//p1, p2的值
printf("pA:%d, pB:%d\n", pA, pB);
system("pause");
return 0;
}
从打印结果来看,p1与p2指向的内存空间的数据是不同,且它们的地址也是不同的。可以看出p1和p2是指向不同块内存的。
那么再来看看下面的实例:它们的值相同吗?它们指向同一块内存吗
char* GetCharInfo1()
{
char *p1 = "abcd";
return p1;
}
char* GetCharInfo2()
{
char *p2 = "abcd";
return p2;
}
int main()
{
char* pA = GetCharInfo1();
char* pB = GetCharInfo2();
//输出p1, p2指向内存空间的数据
printf("pA:%s, pB:%s\n", pA, pB);
//p1, p2的值
printf("pA:%d, pB:%d\n", pA, pB);
system("pause");
return 0;
}
打印结果如下所示:
可以看出p1与p2是指向同一块内存的。我们从它的内存示意图来分析一下:假设栈是开口向上的
当main()函数中执行GetCharInfo1()时,局部指针变量p1指向字符串常量“abcd”所在的内存块,当函数执行完成后,p1便会被系统释放,那么此时p1便不会再指向任何一块内存,另外因为字符串常量是存放在全局区的,由上面的介绍可以知道该区域是在程序结束后由操作系统释放,所以字符串并没有被释放,此时,pA便指向了常量的所在内存块。同理,GetCharInfo2()函数的执行流程是和GetCharInfo1()是一致的。