C++类和new、delete操作符和堆和栈内存的分配
来源:互联网 发布:朋友印象是什么软件 编辑:程序博客网 时间:2024/06/15 05:07
如果你是Java、C#、PHP程序员,那么会对 new 非常熟悉,在这些编程语言中,只能通过 new 来创建对象。在C++中,你可以像定义变量一样来创建对象,如:
- Student stu; //对象已被实例化,已分配内存空间,可以使用了
- stu.say(); //调用成员函数
当发生函数调用时,系统将函数参数、局部变量、局部对象依次压入栈区;函数执行结束,再按照先进后出的原则将它们弹出(销毁)。
对于大部分程序,这不会有什么问题。但当你希望在函数调用结束前销毁对象时,你是无能为力的。或者你希望通过 for 循环来创建多个对象,这种方法同样也做不到。
这个时候 new 和 delete 就派上了用场:使用 new 创建的对象,可以在任意时刻通过 delete 销毁,而且只需要一个指针指向它。
以前面的 Student 类为例,可以这样来动态创建对象:
new Student;也可以使用构造函数:
new Student("小明", 15, 90.5f);这样,就在堆区为对象分配了内存,并调用了构造函数。
但是此时程序员还无法访问这个对象,因为这个对象既没有名字,也没有指针指向它。这种对象称为匿名对象,它确实存在,但无法访问。
用一个指针来指向Student类的对象:
Student *pStu;pStu = new Student("小明", 15, 90.5f);或者:
Student *pStu = new Student("小明", 15, 90.5f);
当不再需要对象时,可以通过 delete 销毁:
delete pStu;这样,就释放掉了对象占用的内存,并调用了析构函数。
需要说明的是:new 在堆区为对象分配内存。与栈区不同的是,堆区内存由程序员分配和释放,系统不会自动销毁,即使函数调用结束了,仍然会保留堆区内存。如果程序员不主动回收堆区内存,那么只能在程序运行结束后由操作系统回收。
为了避免内存泄露,强烈建议 new 和 delete 成对出现,及时销毁不再需要的对象。
例如,下面的代码会造成严重的内存泄露:
- #include <iostream>
- #include <cstdlib>
- using namespace std;
- class Demo{
- private:
- double n;
- double m;
- int i;
- };
- void func(){
- Demo *p = new Demo;
- }
- int main(){
- int i;
- for(i=1; i<=1000000; i++){
- func();
- }
- system("pause");
- return 0;
- }
这是因为每次调用 func 函数,都会创建一个对象,并用 p 指向它。函数运行结束,仅仅释放了指针变量 p 占用的内存,而没有释放 p 所指向的对象占用的内存。
如果在 func 函数中不回收对象内存,那么你将永远无法回收,只能等到程序运行结束由操作系统回收,这就是典型的内存泄露。
另外注意,C语言中的 malloc、free 函数不能用来为对象分配和释放内存。请看下面的例子:
- #include <iostream>
- using namespace std;
- class Demo{
- public:
- Demo();
- ~Demo();
- };
- Demo::Demo(){
- cout<<"Constructor"<<endl;
- }
- Demo::~Demo(){
- cout<<"Destructor"<<endl;
- }
- int main(){
- cout<<"------new------"<<endl;
- Demo *p1 = new Demo; //创建一个对象
- Demo *p2 = new Demo[5]; //创建一组对象
- cout<<"------malloc------"<<endl<<endl;
- Demo *p3 = (Demo*)malloc(sizeof(Demo));
- cout<<"------delete------"<<endl;
- delete p1; //销毁一个对象
- delete[] p2; //销毁一组对象
- cout<<"------free------"<<endl;
- free(p3);
- return 0;
- }
------new------
Constructor
Constructor
Constructor
Constructor
Constructor
Constructor
------malloc------
------delete------
Destructor
Destructor
Destructor
Destructor
Destructor
Destructor
------free------
从程序运行结果可以看出:malloc 虽然分配了内存,但没有调用构造函数;free 虽然释放了内存,但也没有调用析构函数。
0 0
- C++类和new、delete操作符和堆和栈内存的分配
- c++:动态内存分配(new和delete的使用)
- new和delete分配内存
- 类和动态内存分配,类成员的动态内存分配,new,delete,定位new
- new和delete与内存分配
- c++动态内存分配(new/new[]和delete/delete[])
- C++ 方式的内存分配与释放 new 和 delete
- new和delete对结构体分配内存的问题
- 动态内存分配- new/delete 和malloc/free的区别
- 内存的堆分配和栈分配
- 内存的堆分配和栈分配
- 内存的堆分配和栈分配
- 内存的堆分配和栈分配
- 内存的堆分配和栈分配
- 堆内存和栈内存的分配
- C++ 栈和堆 new和delete
- 控制内存分配----重载new和delete & 定位new表达式
- C语言内存分配时的栈和堆
- 【学习笔记】Android-打造炫酷进度条(条形)
- Bootstrap
- 【题】【线段树(不用lazy的区间修改)】NKOJ 2997 狗 【nodgd造水题】
- JAVA面向对象-----接口的特点
- APK 去广告(修改代码级)
- C++类和new、delete操作符和堆和栈内存的分配
- JAVA面向对象-----接口与类、接口之间的关系
- FastDFS特性及问题思考
- 深入浅出 消息队列 ActiveMQ
- 在Qt中读写INI配置文件
- 有 Return 的情况下 Try Catch Finally的执行顺序(详细的代码以及解释)
- List的类类型排序
- 深入理解java反射机制
- HDU 1102 Constructing Roads [已知路径修好求最小生成树]