前言
C最核心的是对内存的操作,本人通过工作中遇到的问题,提出一点点想法,也只是抛砖引玉。
1.内存区间划分
栈区:存放局部变量,函数参数值,由编译器自动分配释放。
堆区:由程序员分配释放。
全局区(静态区):初始化的全局变量和静态变量存储在一块内存,未初始化的存储在相邻内存。
常量存储区: 程序结束由系统释放。
代码区:存放函数体二进制代码。
代码如下(示例):
#include <stdio.h>
int main()
{
int a = 0; //全局初始化
char *p1; //全局未初始化
const int m = 100; //常量存储区
char *p2 = new char[20]; //堆区
}
void func()
{
int b; //栈,局部变量
char *p3; //栈,局部变量
char *p4 = "1234"; //“1234\0”在常量区,p4在栈区
static int c = 0; //全局
p5 = (char *)malloc(10); //堆区
strcpy(p6, "1234"); //“1234\0”在常量区,p6在栈区
//且和p4指向同一块内存
}
2.实例剖析
char[ ] 与char*有许多共同点,代表字符数组,大家知道下面这两个有什么区别么???
char *a = “string1”;
char b[ ] = “string1”;
不同点
a是char* 指针变量,其值(指向)可以改变。
b是char型数组的名字,也是数组元素的首地址,是常量,其值不可以改变。
char[ ]对应的内存区域总是可写的,char*指向的内存有时可写有时可读;
C内存中,局部变量创建创建在栈区,常量创建在文字常量区,a和b都是栈区的局部变量,但是a指向了常量,b指向了变量(指向了自己, &b == b == b[0])。
代码如下(示例):
大家看一下,下面这写法有没有问题
char* func()
{
char a[5] = {"1","2", "3"};
return a;
}
该处的数组a是临时变量,函数返回一个临时变量的地址,在函数结束之后,这个地址很有可能会被占用,所以存在一定风险。
可以改成下面这种
string func()
{
char a[5] = {"1","2", "3"};
return a;
}
这种写法只是返回值类型不同,但是其实代码中已经执行了这步操作。
string func()
{
char a[5] = {"1","2", "3"};
string ss(a); //将a中的值拷贝给ss,而ss是在常量区
return ss;
}
或者还可以写为
char func()
{
static char a[5] = {"1","2", "3"};
return a;
}
将a写在全局区
大家在返回临时变量地址的时候,一定要多加小心哦!