​ ​

注意事项:指针&malloc&返回指针的函数

前言

学C没多久,偶尔要抽出一些时间来总结一下坑点....btw 坑点太多了,只能在后续学习中不断发现,不断填补

正文

一、指针与地址

指针就是地址,地址就是指针
要站在内存的角度来看待和学习指针!

char s[] = "ABC";
s = "DEF" //❌编译出错

char *p = "123";
p = "456"; //✅编译正确

char *q = "ABC";
*q = "CDE"//❌编译出错

  • s 作为首地址,只能被“看做”const 类型的指针,不能改写其值,如果可以赋值,就会改变数组的地址(即数组在内存空间上移动了)。

  • p 作为指针,可以变成指向别的字符串字面量(中的字符)的指针(从p-->1变成p-->4)。赋值后,指针指向新的字符串字面量(中的字符)。注意不要误以为是完全的复制字符串,知识指针指向发生了改变,"123"不能被访问,还是会留在内存空间中。

  • q 作为指针,初始化时已经为其绑定了地址,指向的是q-->A,*q作为指向第一个地址的值,就不能被改变了。也就是说,你可以通过第二种做法去让p指针指向别的地址,但是不能更改原有的字面量的值(一般情况)。

二、指针与malloc()函数

malloc是C的标准库函数之一,用来分配动态内存。
一般来说,由C/C++编译的程序会在运行的时候在内存中占用一些空间,它们分为以下几个部分:
1.二进制代码区 不必过多解释了,就是放二进制代码的地方。
2.常量区 存放文字字符串和常量
3.静态存储区 存放静态和全局变量
4.堆空间 动态内存区,程序员可控制分配和释放的区域。
5.栈空间 由编译器分配内存用于存储函数参数和普通变量。

malloc能操作的是程序中的堆空间,而普通的数组则是存放在栈空间里面的。

int *p;
int *q;
int a = 3;
*p = a;//✅编译正确
*q = 3;//❌编译出错

对于 q,出现错误那是因为即便你定义了指针q,但并未给它分配内存空间。
故我们要用到malloc函数为它分配动态内存。

int *q = (int*)malloc(sizeof(int)*n)// n为希望开辟地址能存放的几个int型的个数
*q = 3;//✅编译正确
free(q);//用完之后释放,free中只能存放指针首地址
*q = NULL//最好加上NULL,防止用完的指针指向别的地方

再来看一个错误

关于 *(p++)和 *(p+1)

在这里插入图片描述
结果
问了其他人为什么会这样:
大佬答:

p++后,你的p已经指向原来的p[1]了,所以此时的p[0]就是原来的p[1],你又*p = 'B' ,所以p[0]为B。此时的p[1]是原来p[1]的下一元素,C规定数组最后一个元素的下一个元素有效,但不保证它的值,所以此时的p[1]值是不确定的,就是你输出的那个?号。

另外别这么写,写*(p + 1) = 'B' 或者
先把p赋给另一个指针再对那个指针自增自减,不然你的内存可能会泄露,比如你这个直接free(p)的话,原来的那个p[0]单元就丢失了。

所以p++(自加) 和 p+1 不要乱用!!!

三、指针函数返回值注意事项

之前看到有个代码,用到了返回指针的函数,但是函数内部却用了局部变量的地址作为返回值,导致输出的结果和要求的不一致,其原因就是指针函数的返回值是有一定要求的,不是什么值都可返回的!

相关知识

  1. 生存期:什么时候这个变量开始出现,到什么时候它消亡了。
  2. 作用域:在(代码的)什么方位内可以访问这个变量(这个变量可以起作用)
  3. 全局变量:定义在函数外面的变量是全局变量,具有全局的生存期和作用域,它们与任何函数都无关,在任何函数内部都可以使用。
  4. 本地变量:函数的每次运行,就产生了一个独立的变量空间,在这个空间中的变量,是函数的这次运行所独有的,称作本地变量
    ●定义在函数内部的变量就是本地变量
    ●参数也是本地变量
  5. 静态本地变量:在本地变量定义时加.上static修饰符就成为静态本地变量, 当函数离开的时候,静态本地变量会继续存在并保持其值,静态本地变量的初始化只会在第一次进入这个函数时做,以后进入函数时会保持上次离开时的值。
    ●静态本地变量实际上是特殊的全局变量,它们位于相同的内存区域,静态本地变量具有全局的生存期,函数内的局部作用域。
    ●static在这里的意思是局部作用域(本地可访问)

接下来就要说返回指针的函数到底要注意哪些点呢

  1. 返回本地变量的地址是危险的❌
  2. 返回全局变量或静态本地变量的地址是安全的
  3. 返回在函数内malloc的内存是安全的,但是容易造成问题
  4. 最好的做法是返回传入的指针

更多关于指针

posted @ 2020-03-31 20:54  Adeleeeeee  阅读(668)  评论(0)    收藏  举报