内存空间
-
代码区
存放二进制程序代码。 -
保留区
0地址开始,存放c的库代码或其他。保留区不是单一的内存区域,而是内存中小部分的无法直接访问的内存区域总称。 -
全局区/静态区
程序中所有全局变量和静态变量都存放在全局区/静态区,程序结束后由操作系统回收此部分内存。分为初始化和未初始化两个相邻区域。 -
堆内存
堆同样是内存区域,但是由程序员分配和释放。程序结束后由操作系统回收此部分内存。C语言的malloc、C++语言的new调用后得到的就是堆内存。存取方式为FILO(First in Last out) -
栈内存
栈存放的变量由编译器自动分配释放,存取速度比寄存器稍低。 -
命令行参数/环境变量
-
内核空间
地址为高地址。
#include <iostream>
using namespace std;
int g1;
int g2 = 0;
int g3 = 1;
static int sg1 = 3;
int main(int argc, char *argv[]) {
static int sl1 = 5;
// 代码区
cout << "main =" << main << endl;
// 全局变量区/静态变量区
cout << "g1 = " << &g1 << endl;
cout << "g2 = " << &g2 << endl;
cout << "(static global) g3 = " << &g3 << endl;
cout << "(static local) sl1=" << &sl1 << endl;
int *p1 = new int;
int *p2 = new int;
// 堆内存区
cout << "heap p1=" << p1 << endl;
cout << "heap p2=" << p2 << endl;
cout << "stack pointer variable p1=" << &p1 << endl;
cout << "stack pointer variable p2=" << &p2 << endl;
int i1 = 100;
int i2 = 101;
// 栈内存区
cout << "stack i1=" << &i1 << endl;
cout << "stack i2=" << &i2 << endl;
return 0;
}
/**
main =1
g1 = 0x555555558154
g2 = 0x555555558158
(static global) g3 = 0x555555558010
(static local) sl1=0x555555558018
heap p1=0x55555556b2c0
heap p2=0x55555556b2e0
stack pointer variable p1=0x7fffffffde78
stack pointer variable p2=0x7fffffffde80
stack i1=0x7fffffffde70
stack i2=0x7fffffffde74
**/
指针及指针变量
- 指针类型
a. 定义指针类型(存放在堆):int *p1 = new int;/(存放在栈中)int *p2=10;
b. 存放在堆的变量被delete以后,指针依然存放值,成为野指针,用if判断仍然为true。
c. delete同一个指针变量两次程序会报错。
d.可以把删除后的指针赋值为nullptr/NULL,这样delete指针变量两次不会出错。
e.存放在栈的变量由编译器自动释放。
#include <iostream>
int main(int argc, char *argv[]) {
// 指针类型
// new int存在堆中
int *p1 = new int;
// *间接符号
*p1 = 101;
// 存在栈中
int i = 10;
int *p2 = &i;
*p2 = 102;
std::cout << "p1 =" << p1 << std::endl;
std::cout << "sizeof(p1) =" << sizeof(p1) << std::endl;
std::cout << "sizeof(*p1) = " << sizeof(*p1) << std::endl;
delete p1;
std::cout << "after delete p1 = " << p1 << std::endl;
// delete操作后p1仍然存放值
if (p1) {
std::cout << "p1 still exists." << std::endl;
}
p1 = nullptr;
if (!p1) {
std::cout << "p1 not exists." << std::endl;
}
delete p1;
return 0;
}
/**result
p1 =0x55555556b2c0
sizeof(p1) =8
sizeof(*p1) = 4
after delete p1 = 0x55555556b2c0
p1 still exists.
p1 not exists.
**/
- 数组类型
a. 定义在堆空间的数组没有begin(),end(),因此不能通过foreach语法遍历数组。
b. new出来的数组使用delete[]释放内存。
#include <cstring>
#include <iostream>
using namespace std;
int main(int argc, char *argv[]) {
// stack
int arr1[10];
memset(arr1, 0, sizeof(arr1)); // get mem size
char str[] = "test";
for (auto s : str) {
cout << s << '-';
}
cout << endl;
cout << "val of str =" << *str << endl;
cout << "sizeof arr1= " << sizeof(arr1) << endl;
cout << "arr1[0] addr= " << &arr1[0] << endl;
cout << "arr1[1] addr= " << &arr1[1] << endl;
// heap
int psize = 10;
int *parr2 = new int[psize];
memset(&parr2, 0, psize * sizeof(int));
cout << "val of parr2 =" << parr2 << endl;
cout << "parr2 addr =" << &parr2 << endl;
cout << "sizeof parr2= " << sizeof(parr2) << endl;
// for(auto& s:parr2) doesn't exist begin()\end()
delete[] parr2;
parr2 = nullptr;
return 0;
}
/**
t-e-s-t--
val of str =t
sizeof arr1= 40
arr1[0] addr= 0x7fffffffde60
arr1[1] addr= 0x7fffffffde64
val of parr2 =0
parr2 addr =0x7fffffffde40
sizeof parr2= 8
*/