c++堆,栈的存储方式及代码内存分配

天大地大妈咪最大 提交于 2020-01-31 22:32:25

使用对象指针
C语言中经典的指针在 C++ 中仍然广泛使用,尤其是指向对象的指针,没有它就不能实现某些功能。

Student stu;
Student *pStu = &stu;

上面代码中创建的对象 stu 在栈上分配内存,需要使用&获取它的地址,例如:

Student stu;Student *pStu = &stu;
pStu 是一个指针,它指向 Student 类型的数据,也就是通过 Student 创建出来的对象。

当然,你也可以在堆上创建对象,这个时候就需要使用前面讲到的new关键字(C++ new和delete运算符简介),例如:
Student *pStu = new Student;
在栈上创建出来的对象都有一个名字,比如 stu,使用指针指向它不是必须的。但是通过 new 创建出来的对象就不一样了,它在堆上分配内存,没有名字,只能得到一个指向它的指针,所以必须使用一个指针变量来接收这个指针,否则以后再也无法找到这个对象了,更没有办法使用它。也就是说,使用 new 在堆上创建出来的对象是匿名的,没法直接使用,必须要用一个指针指向它,再借助指针来访问它的成员变量或成员函数。

栈内存是程序自动管理的,不能使用 delete 删除在栈上创建的对象;堆内存由程序员管理,对象使用完毕后可以通过 delete 删除。在实际开发中,new 和 delete 往往成对出现,以保证及时删除不再使用的对象,防止无用内存堆积。
栈区和堆区详解
1、栈区(stack)—由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈
2、堆区(heap)—
一般由程序员分配释放,若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。-程序结束后有系统释放
4、文字常量区—常量字符串就是放在这里的。 程序结束后由系统释放

5、程序代码区—存放函数体的二进制代码。

//main.cpp  
inta = 0; //全局初始化区  
char*p1; //全局未初始化区  
main()  
{  
int b; //栈   
   char s[] = "abc"; //栈   
   char *p2; //栈    
   char *p3 = "123456"; //123456\0在常量区,p3在栈上。    
   static int c =0//全局(静态)初始化区   
   p1 = (char *)malloc(10);    
    p2 = (char*)malloc(20);    
   //分配得来的10和20字节的区域就在堆区, 但是注意p1、p2本身是在栈中的   
   strcpy(p1,"123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。    
}   

总之:
全局变量和静态变量是全局区,局部变量是在栈区,使用new和malloc函数分配的内存都是通过堆分配。
**大端字节序和小端字节序
**
数据在计算机内部是以小端字节序存储的。因为计算机总是从低字节位进行读取数据更为方便快捷。
栈:在Windows下,栈是向低地址扩展的数据结构,是一块连续的内存的区域。向低字节位扩展(大端字节序?
堆:堆是向高地址扩展的数据结构,是不连续的内存区域(小端字节序?)

栈: 由系统自动分配,速度较快。但程序员是无法控制的。

堆: 由new分配的内存,一般速度比较慢,而且容易产生内存碎片,不过用起来最方便.另外,在WINDOWS下,最好的方式是用VirtualAlloc分配内存,他不是在堆,也不是在栈是直接在进程的地址空间中保留一快内存,虽然用起来最不方便。但是速度快,也最灵活。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!