在编程中,内存分为五大分区:栈区内存,堆区,静态区,常量区,代码区.
看下面一个函数,你能发现它又什么问题?又该如何改正?
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;
}
网友评论