c++中的堆存储和栈存储

首先,我们举一个例子:

void f() { 
    int* p=new int[5];
  } 

看到new,我们首先就应该想到,我们分配了一块堆内存,那么指针p呢?他分配的是一块栈内存,所以这句话的意思就是:在栈内存中存放了一个指向一块堆内存的指针p。在程序会先确定在堆中分配内存的大小,然后调用operator new分配内存,然后返回这块内存的首地址,放入栈中

在C++中,内存分成5个区,他们分别是堆、栈、自由存储区、全局/静态存储区和常量存储区

1.栈

就是那些由编译器在需要的时候分配,在不需要的时候自动清楚的变量的存储区。里面的变量通常是局部变量、函数参数等。

2.堆
就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete。如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收。

3.自由存储区
就是那些由malloc等分配的内存块,他和堆是十分相似的,不过它是用free来结束自己的生命的。

4.全局/静态存储区,全局变量和静态变量被分配到同一块内存中,在以前的C语言中,全局变量又分为初始化的和未初始化的,在C++里面没有这个区分了,他们共同占用同一块内存区。

5.常量存储区
这是一块比较特殊的存储区,他们里面存放的是常量,不允许修改(当然,你要通过非正当手段也可以修改)

注:

1)在程序中,使用new运算符在堆中开辟一个空间之后,在数据使用完后,一定要释放在堆中开辟的空间,否则会出现内存泄露,运算符delete用于释放new运算符在堆中开辟的空间。

2)此外,在释放使用new运算符为数组分配的空间时,需要使用delete[]来释放。

3)在程序中使用new运算符在堆中分配空间时,注意不要轻易修改指针指向的地址,因为当前指针指向了堆空间的地址,如果将其再指向其他地址,将导致无法释放堆空间,
如:

int *data = new int[3];
int num = 10;
data = #

上述代码中,指针data最初指向堆中的一个地址空间,然后将其指向了整型变量num,这样将导致new运算符在堆中开辟的空间无法被释放,最终会导致内存泄露,这是不允许的。

例子程序

int a = 0; //全局初始化区 
char *p1; //全局未初始化区 
main() 
{ 
int b; //栈 
char s[] = "abc"; //栈 
char *p2; //栈 
char *p3 = "123456"; //123456在常量区,p3在栈上。 
static int c =0//全局(静态)初始化区 
p1 = (char *)malloc(10); 
p2 = (char *)malloc(20); //分配得来得10和20字节的区域就在堆区。
strcpy(p1, "123456"); 
//123456放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。 
}

参考博客:
C++存储区域详解
C/C++堆栈

你可能感兴趣的:(c++)