[C++杂记] C++如何管理内存区

首先从一个现象出发:

代码段1:

char a[] = "sdf";
a[0] = 'a';
cout << a;


代码段2:
char *a = "sdf";
a[0] = 'a';
cout << a;

代码段1的运行结果为adf,代码段2会在第2行发生运行时错误。

要解释上面的不同结果,必须了解一下C++的存储区。C++在运行程序时,在内存中有5块不同的区域来存储数据,分别为栈、堆、全局\静态区、常量区、代码区。

栈:由程序自动分配并且释放,多用来存储局部变量、函数参数,在函数调用时使用。

堆:由程序员分配并且释放,在C中由malloc创建,在C++中由new创建。只能通过指针访问。

全局\静态区:存放程序的全局变量和静态变量。在C中,初始化的变量和未初始化的变量分开存放,在C++中,存放在一起。

常量区:1、存放被const修饰的变量。

               2、存放类似“123456”这样的字符串字面值。

代码区:存放程序的二进制代码。


代码段1中,“sdf”字面值存储在常量区,字符数组a存储在栈中,并且将字面值“sdf”也拷贝了一份存储在栈中。第2行改变字符数组的首元素时,修改了存储在栈中的元素,因此修改成功。

代码段2中,“sdf”字面值存储在常量区,字符指针存储在栈中,但是该指针指向的是常量区的“sdf”。第2行设法改变常量区的字符串常量,就会出现访问内存错误。抛出runtime error。


1、栈和堆的区别在于栈是由程序自动分配和释放,堆是由程序员通过代码显式分配和释放。栈和堆中的元素都是可以通过代码修改的。除了new出的空间,大部分变量存在栈中。这些变量都有明确的大小,一个紧接着一个排列在栈中。

2、数组之所以必须指定其大小,就是因为数组要存储在栈中,由程序自动分配和释放,必须明确知道大小。通过new分配的空间在堆中,大小可以在程序运行时指定。

3、指针不一定都是通过new创建的指向堆的,比如代码片段2指向常量区的指针。


引用:

1、ChinaUnix [C] 请教下高手,char *str为什么会默认为 const char *str?

2、徐中 BizTalk 产品专家 [C++] 堆栈与堆的概念

3、csdn博客 Kaho的专栏 【C++】堆栈

4、百度知道 C++ const char* 指针相等问题

5、csdn博客 飞鸽沟通最简单  浅谈C/C++堆栈指引——C/C++堆栈很强大

6、C语言中文网 C++二维数组讲解、二维数组的声明和初始化



你可能感兴趣的:([C++杂记] C++如何管理内存区)