1.C语言内存分配
栈区(Stack):由编译器自动分配释放,存放函数的参数值,局部变量等信息。
堆区(Heap):由程序员分配释放,系统会在程序结束时回收。
全局区(静态区):全局和静态变量存放在这里,由系统回收。
文字常量区:存放常量字符串,由系统回收。
程序代码区:。
C语言堆内空间申请函数为 malloc(size)
2.二级指针
一级指针类型如 int* ,那么二级指针类型定义为 int** ,以此类推,当然三级以上指针类型,我们应该会极少极少使用。
先分析一下二级指针类型的存在意义吧,我的理解是,它让我们可以在另一函数中初始化一个指针(因为C语言函数传参是值传递)。先看一段代码:
char* c1;
printf("&c1 = %p\n",&c1);
printf("c1 = %p\n",c1);
c1 = malloc(10);
printf("&c1 = %p\n",&c1);
printf("c1 = %p\n",c1);输出结果:
&c1 = 0x7fff52441c38
c1 = 0x0
&c1 = 0x7fff52441c38
c1 = 0x600000014960 我们用malloc函数向系统申请一块内存,并把地址给了 c1,这样我们就可以使用这段内存了,但是我们如果想在一个函数中初始化 c1,该怎么办,假如用下面方法:
char* c1;
printf("&c1 = %p\n",&c1);
printf("c1 = %p\n",c1);
c_init(c1);
printf("&c1 = %p\n",&c1);
printf("c1 = %p\n",c1);
void c_init(char* p){
printf("&p = %p\n",&p);
printf("p = %p\n",p);
p = malloc(100);
printf("&p = %p\n",&p);
printf("p = %p\n",p);
}输出:
&c1 = 0x7fff59f42c38
c1 = 0x0
&p = 0x7fff59f42bc8
p = 0x0
&p = 0x7fff59f42bc8
p = 0x6000000de0d0
&c1 = 0x7fff59f42c38
c1 = 0x0可见,这样并不能成功,C语言函数传参属于值传递,如果我们想通过参数传递,在一个函数中改变外面这个指针变量的值,就必须通过获得这个指针变量的地址,指针的指针,这里就想到了二级指针,那么:
char* c1;
printf("&c1 = %p\n",&c1);
printf("c1 = %p\n",c1);
c_init(&c1);
printf("&c1 = %p\n",&c1);
printf("c1 = %p\n",c1);
void c_init(char** p){
*p = malloc(100);
}输出结果:
&c1 = 0x7fff5fb2fc38
c1 = 0x0
&c1 = 0x7fff5fb2fc38
c1 = 0x6000000dbdd0成了!仔细分析,确实应该这样,我们不能通过值改值,应该追其地址,通过地址区改,变量名也是因为和地址绑定,才能修改值的。
下一篇
深入理解C语言指针(三) 有关数组和char**