C语言跟C++语言存储区分类大体一样,但仍有些细微差别。
一、在C语言中,内存区域可以分为以下5类
1、栈,由编译器负责自动分配与释放,一般在函数体类定义的局部变量与非main函数参数都放在栈内;
2、堆,由程序员主动分配和释放,若程序员不释放,则只会在程序退出的时候被系统释放,用malloc、calloc、realloc等函数申请到的内存区域放在堆上,需要使用free函数释放相应内存,否则只有在程序退出时才会被系统所回收;
3、全局/静态存储区,专门存放全局变量和静态变量的区域,它还可以再细分为两个区域,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和静态变量在相邻的另一块区域, 程序退出时才释放,例如在函数体外定义的全局变量和static修饰的变量;
4、常量存储区,专门用于存放常量的区域, 程序退出时才释放,例如形如“cpplive”之类的字符串。
详见如下示例:
int a = 0; //全局初始化区 char *p1; //全局未初始化区 void main() { int b; //栈 char s[] = "abc"; //栈 char *p2; //栈 char *p3 = "123456"; //“123456”存放在常量区,p3存放在栈上 static int c = 0; //全局(静态)初始化区 p1 = (char *)malloc(10); //申请10字节的内存区分配在堆区 p2 = (char *)malloc(20); //申请20字节的内存区分配在堆区 strcpy(p1, "123456"); //”123456”存放在常量区,编译器可能会将它与p3所指向的"123456"优化成一块 }
二、在C++中,内存区域可以分为以下5类
1、栈,由编译器负责自动分配与释放,一般在函数体类定义的局部变量与成员函数参数都放在栈内;
2、堆,专指那些由new申请的内存区域,其释放不由编译器负责,需要程序员指定应用程序去释放,一般一个new对应一个delete,若程序员没有释放,只有在程序退出时才会被操作系统所回收;
3、自由存储区,专指那些由malloc、calloc、realloc等函数分配的内存区域,它和堆十分相似,但它是用free释放自身的;
4、全局/静态存储区,专门用于存储全局变量和静态变量的内存区域,跟C语言不同的是,C++不区分初始化的和未初始化的全局变量,它们占用同一块内存区域。
5、常量存储区,专门用于存放常量的区域, 程序退出时才释放,例如形如“cpplive”之类的字符串。
C/C++内存地址分配简介
1、在栈内存中,变量的分配方向是朝下的,即先分配的地址大,后分配的地址小。
2、在堆、自由存储区、全局/静态存储区内存中,变量的分配方向是朝上的,即先分配的地址小,后分配的地址大。
3、一个变量的地址由它所占地址空间的最低位表示的。
0xbfcef394 0x34
0xbfcef396 0x12
所以变量0x1234(即十进制数4660)的地址为0xbfcef394。
4、小端模式的CPU,低地址存低位,高地址存高位。
5、大端模式的CPU,低地址存高位,高地址存低位。
0xbfcef394 0x34
0xbfcef396 0x12
所以以上变量在小端模式CPU平台下的值为0x1234(即十进制数4660),大端模式CPU平台下的值为0x3412(即十进制数13330)。
6、联合体union的所有成员都从低地址开始存放。
最后,咱们看一个例子就一目了然了:
#include <iostream> #include <stdio.h> using namespace std; class A { public: short m_a1; short m_a2; A() { m_a1=1; m_a2=2; } void fun() { printf("%d, %d\n", m_a1, m_a2); cout << "m_a1_addr:" << &m_a1 <<endl; cout << "m_a2_addr:" << &m_a2 <<endl; } }; class B { public: int m_a3; B() { m_a3=3; } void fun() { printf("%d\n", m_a3); cout << "m_a3_addr:" << &m_a3 <<endl; } }; int main() { A a; B *pb; int t1; int t2; static int t3; static int t4; cout << "m_a1_addr=" << &(a.m_a1) <<endl; cout << "m_a2_addr=" << &(a.m_a2) <<endl; cout << "m_a3_addr=" << &(pb->m_a3) <<endl; pb = (B *)&a; pb->fun(); cout << "t1_addr=" << &t1 << endl; cout << "t2_addr=" << &t2 << endl; cout << "t3_addr=" << &t3 << endl; cout << "t4_addr=" << &t4 << endl; return 0; } 运行结果: m_a1_addr=0xbfe4e15c m_a2_addr=0xbfe4e15e m_a3_addr=0x8048980 131073 m_a3_addr:0xbfe4e15c t1_addr=0xbfe4e154 t2_addr=0xbfe4e150 t3_addr=0x804a0d8 t4_addr=0x804a0dc
运行结果说明:131073 = 2^17 + 1 , 其他的结果也就不解释了,看了前面的说明应该理解的。
除非注明,文章均为CppLive 编程在线原创,转载请注明出处,谢谢。