C++指针 接收c++字符串指针,c++字符串指针是在堆还是栈,空间会释放吗?

前言:对于程序中使用的对象都有着严格的生存期。对于局部对象,当我们调用局部对象所在的程序时为其在栈上分配内存空间,程序调用完成释放该对象的内存空间。对于全局对象,其在程序启动时在静态存储区分配内存空间,在程序结束时销毁内存空间。对于局部static对象在第一次使用前分配内存空间,在程序销毁时释放内存空间。除了自动和static对象外,C++还支持动态内存分配。动态分配的对象的生存期由程序员自己控制,在堆上申请,手动释放。这属于在堆上申请内存空间,及数据存储在堆内存上。C++的内存空间分为以下5个部分:静态存储区:内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。它主要存放静态数据(局部static变量,全局static变量)、全局变量和常量。栈区:在执行函数时,函数(包括main函数)内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(任何变量都处于栈区,例如int a[] = {1, 2},变量a处于栈区。数组的内容也存在于栈区。)堆区:亦称动态内存分配。程序在运行的时候用malloc或new申请任意大小的内存,程序员自己负责在适当的时候用free或delete释放内存。动态内存的生存期可以由我们决定,如果我们不释放内存,程序将在最后才释放掉动态内存。 但是,良好的编程习惯是:如果某动态内存不再使用,需要将其释放掉,并立即将指针置位NULL,防止产生野指针。文字常量区:常量字符串放在这里,程序结束后由系统释放。程序代码区:存放函数体的二进制代码。指针:函数指针指向Code区,是程序运行的指令代码,数据指针指向Data,Heap,Stack区,是程序依赖以运行的各种数据。注:在文件作用域声明inline函数默认为static存储类型,const常量默认为static存储,如果加上extern,则为外部存储类型。补充说明:1、全局静态变量:定义:.在全局变量之前加上关键字static,全局变量就被定义成为一个全局静态变量。说明:1)内存中的位置:静态存储区(静态存储区在整个程序运行期间都存在)2)初始化:未经初始化的全局静态变量会被程序自动初始化为0(自动对象的值是任意的,除非它被显示初始化)3)作用域:全局静态变量在声明它的文件之外是不可见的。准确地讲从定义之处开始到文件结尾。定义全局静态变量的好处:1)不会被其他文件所访问,修改。2)其他文件中可以使用相同名字的变量,不会发生冲突。2、局部静态变量:定义:在局部变量之前加上关键字static,局部变量就被定义成为一个局部静态变量。说明:1)内存中的位置:静态存储区2)初始化:未经初始化的局部静态变量会被程序自动初始化为0(自动对象的值是任意的,除非他被显示初始化)3)作用域:作用域仍为局部作用域,当定义它的函数或者语句块结束的时候,作用域随之结束。注:当static用来修饰局部变量的时候,它就改变了局部变量的存储位置,从原来的栈中存放改为静态存储区。但是局部静态变量在离开作用域之后,并没有被销毁,而是仍然驻留在内存当中,直到程序结束,只不过我们不能再对它进行访问。当static用来修饰全局变量的时候,它就改变了全局变量的作用域(在声明它的文件之外是不可见的),但是没有改变它的存放位置,还是在静态存储区中。3、堆与栈的区别:主要有6点区别:1、管理方式不同:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生memory leak。2、空间大小不同:一般来讲在32位系统下,堆内存可以达到4G的空间,从这个角度来看堆内存几乎是没有什么限制的。但是对于栈来讲,一般都是有一定的空间大小的,例如,在VC6下面,默认的栈空间大小是1M(好像是,记不清楚了)。当然,我们可以修改: 打开工程,依次操作菜单如下:Project->Setting->Link,在Category 中选中Output,然后在Reserve中设定堆栈的最大值和commit。 注意:reserve最小值为4Byte;commit是保留在虚拟内存的页文件里面,它设置的较大会使栈开辟较大的值,可能增加内存的开销和启动时间。3、产生碎片不同:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低。对于栈来讲,则不会存在这个问题,因为栈是先进后出的队列,他们是如此的一一对应,以至于永远都不可能有一个内存块从栈中间弹出,在它弹出之前,在他上面的后进的栈内容已经被弹出,详细的可以参考数据结构,这里我们就不再一一讨论了。4、生长方向不同:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长。5、分配方式不同:堆都是动态分配的,没有静态分配的堆。栈有2种分配方式:静态分配和动态分配。静态分配是编译器完成的,比如局部变量的分配。动态分配由alloca函数进行分配,但是栈的动态分配和堆是不同的,它的动态分配是由编译器进行释放,无需我们手工实现。6、分配效率不同:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高。堆则是C/C++函数库提供的,它的机制是很复杂的,例如为了分配一块内存,库函数会按照一定的算法(具体的算法可以参考数据结构/操作系统)在堆内存中搜索可用的足够大小的空间,如果没有足够大小的空间(可能是由于内存碎片太多),就有可能调用系统功能去增加程序数据段的内存空间,这样就有机会分到足够大小的内存,然后进行返回。显然,堆的效率比栈要低得多。从这里我们可以看到,堆和栈相比,由于大量new/delete的使用,容易造成大量的内存碎片;由于没有专门的系统支持,效率很低;由于可能引发用户态和核心态的切换,内存的申请,代价变得更加昂贵。所以栈在程序中是应用最广泛的,就算是函数的调用也利用栈去完成,函数调用过程中的参数,返回地址,EBP和局部变量都采用栈的方式存放。所以,我们推荐大家尽量用栈,而不是用堆。 虽然栈有如此众多的好处,但是由于和堆相比不是那么灵活,有时候分配大量的内存空间,还是用堆好一些。注: 无论是堆还是栈,都要防止越界现象的发生(除非你是故意使其越界),因为越界的结果要么是程序崩溃,要么是摧毁程序的堆、栈结构,产生意想不到的结果,就算是在你的程序运行过程中,没有发生上面的问题,你还是要小心,说不定什么时候就崩掉,那时候debug可是相当困难的)。demo如下://main.cpp
int a = 0;
//全局初始化区
char *p1;
//全局未初始化区
int 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"优化成一个地方。
}
可供参考的博文:https://blog.csdn.net/hushpe/article/details/45396059https://blog.csdn.net/u010977122/article/details/53099425https://blog.csdn.net/slj_win/article/details/8608436}

我要回帖

更多关于 c++字符串指针 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信