极客班GeekBand - C++第一次课程辅导 - 李建忠
- 极客班GeekBand - C第一次课程辅导 - 李建忠
- 栈Stack VS 堆heap
- 堆对象的空间分析
- 栈对象的空间分析
- 变量模型与使用
- 课程总结
栈(Stack) VS. 堆(heap)
- 栈
- 由系统自动管理,以执行函数为单位
- 空间大小编译时确定(参数+局部变量)
- 函数执行时,系统自动分配一个stack
- 函数执行结束时,系统立即自动回收stack
- 堆
- 在c++中由程序员手动控制
- 手动分配new和malloc
- 手动释放delete和free
- 具有全局性,总体无大小限制
- 容易造成内存泄露
堆对象的空间分析
栈对象的空间分析
变量模型与使用
- 三种变量模型
- 对象
- 指针
- 引用
MyClass c; //对象 一定在栈上
MyClass* pc; //指针 要问自己是栈指针,还是堆指针
MyClass& c2 = c; //引用 要问自己是栈引用,还是堆引用
c = *pc; //“解引用” 可指向堆对象,也可以指向栈对象
pc = &c; //“取地址”
堆引用
MyClass* pc2 = new MyClass();
MyClass& c3 = *pc2;
- 三种使用场景
- 声明对象
- 传参
- 返回值
三种传参方式
//对象
void func1(MyClass c) {
}
//指针
void func2(MyClass* pc) {
}
//引用
void func3(MyClass& mc) {
}
一个原则:谁分配谁释放
MyClass* pc = new MyClass();
func2(pc);
delete pc;
一个荒谬的做法,违反谁分配谁释放
void func3(MyClass& mc) {
MyClass* p = &mc;
delete p;
}
const引用是by value的替代品,const引用可以禁止引用修改原对象值
void func3(const MyClass& mc) {
}
三种传参方式,是否调用拷贝构造函数
MyClass c1;
func1(c1); //调用拷贝构造
func2(&c1); //不调用拷贝构造函数
func3(c1); //不调用拷贝构造函数
三种返回值方式分析
MyClass func1() {
MyClass c1;
return c1;
//下面的方式会造成内存泄露,违反“谁创建,谁释放”。
MyClass* pc2 = new MyClass();
return *pc2;
}
MyClass* func2() {
//函数返回后c1被销毁。
MyClass c1;
return &c1;
//内存泄露
MyClass* pc2 = new MyClass();
return pc2;
}
MyClass& func3() {
//函数返回后c1被销毁。
MyClass c1;
return c1;
//内存泄露
MyClass* pc2 = new MyClass();
return *pc2;
}
MyClass& c4 = func3();
delete &c4;
传进函数的地址,可以再返回去。
MyClass& func4(MyClass& c) {
return c;
}
一种编程语言能不能只有栈而没有堆?
不行,栈是静态的,编译时就确定。堆是动态的。
一种编程语言能不能只有堆而没有栈?
不行,没有栈就没有函数。
课程总结
- 掌握内存模型分析方法——画运行时内存图
- 掌握堆、栈概念
- 掌握指针、引用、对象
- 探微知著:魔鬼尽在细节中
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-12-19 15:05:00