黑马程序员c++ p84-p88 有感,下附链接
黑马程序员匠心之作|C++教程从0到1入门编程,学习编程不再难_哔哩哔哩_bilibili
1.代码区
顾名思义,该区储存代码,以二进制形式存放函数体,由操作系统管理
代码区两个特点:
共享:该exe需要多次使用,不需要每次使用编译新的代码
只读:防止程序意外更改指令
2.全局区(静态区)
该区储存的值不会随着exe程序执行完毕而释放
储存变量有:全局变量, 静态变量: 静态全局变量(static),静态局部变量(static), 常量: 全局常量(const),字符串常量("string")
注意:
1.字符串常量!=字符串
string str="hello world";
cout<<&str;
与
cout<<&"hello world";
二者完全不一样
2.静态局部变量不储存在全局区,该类型与局部变量储存在一起
猜测是代码区
3.static修饰后,该变量可以在程序运行过程中更改数值,但程序结束后,该值不会被释放
详见: static静态变量的理解 - dzqdevin - 博客园 (cnblogs.com)
辨析常量变量种类的代码:
#include<iostream>
using namespace std;
const int c = 10;
static int e = 10;
int main() {
const int a = 10;
int b = 10;
static int d = 10;
string str = "hello world";
cout << "局部常量 = " << &a << endl;
cout << "局部变量 = " << &b << endl;
cout << "全局常量 = " << &c << endl;
cout << "静态局部变量 = " << &d << endl;
cout << "静态全部变量 = " << &e << endl;
cout << "字符串变量 = " << &str << endl;
cout << "字符串常量 = " << &"hello world" << endl;
}
3.栈区
由编译器自动分配和释放,存放函数的参数值和局部变量等
比如被调函数的某些变量值(非new或malloc情况下)
栈区储存的数据在执行完毕后自动释放 (某些情况下会保存一次命令,见注意2)
注意:
1.不要返回局部变量的地址,第一次返回程序会在参数中保留地址,第二次再次使用返回的值,会被栈收回,输出乱码
相关示例:
1.int a 由主函数传入
#include<iostream>
using namespace std;
int* func(int a) {
int* p = &a;
//cout << a << endl;
//cout << *p << endl;
return p;
}
int main() {
int a = 10;
int* p = func(a);
cout << *p << endl;
cout << *p << endl;
}
猜测这里对由func函数传入的局部变量a的地址p解引后两次乱码原因是:
局部变量a是由主函数传入的,对比接下来的func函数内首次声明的情况
2.int a在被调函数内声明
#include<iostream>
using namespace std;
int* func();
int main() {
int* p = func();
cout << *p << endl;
cout << *p << endl;
}
int* func() {
int a = 10;
int* p = &a;
return p;
}
第一次可以打印出正确数值,因为编译器做了保留
第二次数据不会保留了
4.堆区
由程序员分配和释放,如果程序员未主动释放将由系统在程序执行完毕后自动释放
在c++中,主要用new在堆区开辟内存
思考: c++中的malloc与new的区别是?
见 5.自动储存区
对比于栈区,被调函数执行完毕,栈区储存的数据会被自动销毁,但如果指针p储存一个堆区的值,那么即使被调函数执行完毕,就算变量名p消失,p所储存的地址值也不会消失,此时p储存的堆区地址值被主函数的指针p所指向
#include<iostream>
using namespace std;
int* func();
int main() {
int* p = func();
cout << *p << endl;
cout << *p << endl;
delete p;
//cout << *p << endl;
//第九行会警告读取访问冲突,因为没有权限对该地址的值进行访问,因为new申请的内存已被释放了
}
int* func() {
int* p = new int(10);
return p;
}
类比开房: delete之后,房间p住的人已经更改了,这时再去房间p做各种操作会引发异常,比如被拷走
5.自由储存区
在c++中,malloc函数申请的内存就在这里
自由储存区与堆的区别: C++ 自由存储区是否等价于堆? - melonstreet - 博客园 (cnblogs.com)
C++ 自由存储区是否等价于堆? - 知乎 (zhihu.com)
自由储存区是c++真正的区,heap堆只是个c语言衍生的概念
new与malloc区别 首先,new不需要程序员规定申请内存大小,会自动分配