一、指针基础
1.概念
- 计算机中的内存中的每一个字节都有一个地址,地址用16进制表示。一般可以理解为指针就是地址,地址就是指针。
- 定义指针
int* ptr;//定义了一个指向整数的指针,ptr中可以存储int类型的首个字节的地址,int就是让它连续读sizeof(int)个字节。
--------------------------------------------
int a =10;
int* ptr = &a;//ptr现在存储的是a的地址,是int*类型
----------------------------------------------
int value = *ptr //ptr解引用,也就是降级,故value被赋值为10
“*”是间接访问操作符,作用是通过指针访问存储在该地址上的值
- 指针是一个变量,它存储了另一个变量的内存地址。换句话说,指针本身存储的是一个内存地址,而不是一个具体的值。
- 指针有类型,这意味着它指向的是特定类型的数据。例如,int* 是一个指向整数的指针,char* 是一个指向字符的指针,double* 是一个指向双精度浮点数的指针。
2.野指针
- 野指针(dangling pointer)是指向已释放或未分配内存区域的指针。它们通常是在以下情况下产生的:
1.指针没有初始化:指针变量被声明但未初始化,指向一个不确定的位置。
#include <stdio.h>
int main() {
int* ptr; // 未初始化的指针,指向不确定的位置
*ptr = 10; // 未定义行为,可能会导致程序崩溃
return 0;
}
2.指针指向的内存被释放:指针指向的内存被释放后,指针未被置为 NULL 或未重新指向有效内存。
#include <stdio.h>
#include <stdlib.h>
int main() {
int* ptr = (int*)malloc(sizeof(int)); // 动态分配内存
*ptr = 10;
free(ptr); // 释放内存
*ptr = 20; // 未定义行为,ptr 成为野指针
return 0;
}
3.超出作用域:局部指针变量指向的内存超出其作用域,导致指针悬挂
#include <stdio.h>
int* danglingPointer() {
int localVar = 10;
return &localVar; // 返回局部变量的地址,局部变量在函数返回后被销毁
}
int main() {
int* ptr = danglingPointer();
printf("%d\n", *ptr); // 未定义行为,ptr 是一个野指针
return 0;
}
- 避免野指针的方法
1.初始化指针:声明指针时将其初始化为 NULL。
2.释放内存后将指针置为 NULL:释放动态内存后,将指针置为 NULL。
3.慎用局部指针返回值:不要返回指向局部变量的指针。可以使用动态内存分配或者静态变量解决此问题。
4.定期检查指针有效性:在使用指针前,检查其是否为 NULL。
if (ptr != NULL) {
// 安全使用指针
}
指针变量
1.存储指针的变量称之为指针变量,即指针变量空间中存储的是地址。
2.指针变量中存储的都是其他变量的首地址。
3.存储一级指针地址的指针变量,称之为二级指针。依次类推,就是多级指针
int*** ptr3 ---->ptr3中可以存储int**类型变量空间的首地址,ptr3自己则是int ***类型
4.指针变量的大小与指针变量类型没有关系,而是与操作系统有关系,32位操作系统地址空间最大为2^32,即指针变量为4个字节。64位操作系统依此类推为8个字节。
5.&取变量首地址,但无法获取常量的地址,打印地址则用%p
6.指针变量定义时可以给一个具体的指针,如果现在没有具体的值,那么将该指针指向null,占位。
int* pe;
pe = &e;//等价于int* pe=&e;
---------------------------------------------------------
int* pc=&b;//将b变量的首地址,赋值给pc,此时可以说pc指向b
int* pd=pc;//将pc空间的数据赋值给pd,那么可以说pd和pc指向同一个内存空间
7.在口