C++内存中的堆和栈

我们把一个C++程序在运行的时候所占据的内存空间,分成四个部分

栈区

堆区

全局区/静态区

常量区

在C++程序的内存空间中,我们在代码中声明的局部变量,以及函数的形式参数,都保存在栈区中,这部分内存在程序运行的时候会自动分配,而在不需要的时候也会自动释放,并不需要去手动维护

而我们使用new或者malloc函数进行动态内存分配后,系统为我们划分的内存空间,就来自于堆区,因为程序自己不知道这些动态内存到什么时候会派不上用场,所以程序并不会对这部分分配的内存做任何处理

如果不及时使用new或delete运算符的话,会造成内存泄漏

存储规则:

假设程序内存地址从0x0000开始,到0xFFFF结束,我们可以看到随着存储内容的增大,堆会从低地址开始到高地址结束,

栈则相反,如果内存空间用完的话,则会发生segment fault,就是段错误

具体案例:

int myFunc2(){ 
    int *p=new int[2];    //p是局部变量,保存在栈区,而p指向的具有两个元素的数组,作为一个堆对象而位于堆区中,不要把指针变量和指针所指变量搞混了
}

p是指针局部变量,保存在栈区,而指向的两个元素数组,作为一个堆对象位于堆区中

切记不要搞错

还有要注意深复制的影响:

#include <iostream>
using namespace std;

struct Point
{
	int x;
	int y;
};


int main() {

	Point a{ 1,2 };
	Point b = a;

	Point *c = new Point{ 3,4 };
	Point *d = c;

	a.x = 10;
	c->x = 10;

	cout << b.x << "  " << d->x << endl;


	system("PAUSE");
}

因为c和d在这里共享了一个地址,所以会发生深复制,即使给c赋值也会造成d发生同样的赋值,因为他们共享了一个地址

检测方法:在在cpp文件处进行预定义

#define _CRTDBG_MAP_ALLOC

#include <stdlib.h>   //头文件

#include <crtdbg.h>

#define NEW_WITH_MEMORY_LEAK_CHECKING new(_NORMAL_BLOCK, __FILE__, __LINE__)

#define new NEW_WITH_MEMORY_LEAK_CHECKING

 

程序运行完毕:定义以下函数

_CrtDumpMemoryLeaks();

 

猜你喜欢

转载自blog.csdn.net/alex1997222/article/details/81270817