C语言栈区与堆区浅谈

作者: 三木成森 | 来源:发表于2015-08-22 16:43 被阅读765次

    在编程中,内存分为五大分区:栈区内存,堆区,静态区,常量区,代码区.

    看下面一个函数,你能发现它又什么问题?又该如何改正?

    char * getString() {

    char str[20] = "iPhone";

    return str;

    }

    首先,我们先来了解下五大分区的作用,然后上面的getString()函数的错误,就迎刃而解了.

    栈区内存:是给函数里面的局部变量和形参分配内存.当发生函数调用时,操作系统就会为这个函数里面的所有局部变量和形参分配内存, 当函数调用完毕时, 所有为这个函数分配的栈区内存就会被系统回收.

    堆区:由程序员自己负责分配和释放. 有分配就得有释放, 否则会导致内存泄露

    静态区:用static修饰的变量和全局变量会被分配在静态区,静态区内存由操作系统负责分配和释放(并且使用static修饰的变量只会被初始化一次)

    常量区:代码里写的数值常量,字符串常量,都是存储在常量区的,常量区的内存也是操作系统负责分配和释放.常量区的最大特点是内容不可修改.

    我们已经了解了五大分区每个分区的特性,那么接下来,我们来分析一下getString()函数错在哪里?

    在getString函数中:char str[20]= "iPhone";定义了一个长度为20的字符数组,因为是函数里面的局部变量,因此它的内存是在栈区存放,也就是说,现在栈区里面申请了一块内存区域用来存放getString函数里面的局部变量,"iPhone"这个字符数组也就保存在了这个栈区内存.

    接下来return str;返回数组的地址.函数调用结束后,系统将会对栈区的getString的内存进行回收.也就是说,返回的str这个指针指向数组已经不存在了.那么我们该如何改进才能拿到这个"iPhone"字符数组呢?

    这就需要利用堆区的特性来进行改进.改进后函数如下:

    char * getString() {

             char * str = malloc(10) ;//动态申请一个堆区内存,来存储字符

             strcpy(str , "iPhone");//把常量区的"iPhone"字符拷贝到堆区的内存中

              return str;//返回的是堆区的地址

    }

    通过这样改进后我们就能拿到一个指向堆区的指针.(调用过这个函数后,要记得释放free(); )

    char * getString() {

    char str[20] = "iPhone";

    return str;

    }

    相关文章

      网友评论

      本文标题:C语言栈区与堆区浅谈

      本文链接:https://www.haomeiwen.com/subject/gpuoqttx.html