2025_2_4 C语言中关于free函数及悬空指针,链表的一级指针和二级指指针

1.free函数

  • free函数所接受的参数只能是动态分配出来的内存,,否者free的行为是未定义的
  • 同一片内存空间不能被free两次

free过后的内存可能会引发悬空指针的问题

2.悬空指针

悬空指针的问题主要是free过后的内存空间,原先指向这片空间的指针没有做处理,这个指针就是悬空指针,因为它指向的内存空间已经被free了

悬空指针问题很难被发现,因为可能有多个指针指向被free的内存空间,这些指针就都变成悬空指针了

cpp 复制代码
char* p = malloc(10);
char* q = p;

free(p);
//p和q都是悬空指针了,下面两个操作会出错
strcpy(p, "abc");
strcpy(q, "dcf");

调用了strcpy(p, "abc")和strcpy(q, "dcf")。这两个操作都是试图向已经被释放的内存中写入数据。由于内存已经被释放,程序不再拥有这块内存的所有权,此时写入操作是非法的

所以,处理悬空指针的方法就是将其重新复制为NULL

cpp 复制代码
char* p = malloc(10);
char* q = p;
free(p);

p = NULL:
q = NULL;

3.链表的一级指针和二级指指针

宗旨:想修改哪个变量,就传递哪个变量的地址

  1. 修改指针变量指向的对象------>一级指针

    比如:
    遍历链表
    修改节点数据
    删除/插入中间或尾部节点(通过前驱节点操作)

  2. 修改指针变量的值(指针变量的指向)------>二级指针
    比如:
    头插法插入节点(修改头指针指向新节点)
    删除头节点(头指针需指向下一个节点)
    初始化空链表(首次插入节点时需修改头指针)

指针变量存储的是内存地址,当我们将指针作为参数传递给函数时,实际上是传递了该指针的副本。如果函数内修改了这个副本指向的内容,那么原指针指向的内容也会被修改,因为副本和原指针指向同一块内存。但如果需要修改指针本身(即让指针指向另一个地址),则需要传递指针的指针,也就是二级指针,这样函数才能修改原指针的值。

cpp 复制代码
typedef struct node_s {
	int date;
	struct node_s* next;
}node;

node* add_node(node** plist, int date) {
	//创建节点空间
	node* new_node = malloc(sizeof(node));
	if (new_node == NULL) {
		printf("add_node faild in add_node!\n");
		exit(1);
	}
	//头插法
	new_node->date = date;
	new_node->next = *plist;
	*plist = new_node;
	//返回头指针
	return *plist;
}

int main() {
	node* list = NULL;
	//list可以接收头指针
	add_node(&list, 1);
	add_node(&list, 2);
	add_node(&list, 3);
	add_node(&list, 4);
	return 0;
}

上述代码在插入结点的时候用到的是头插法,需要改变头节点的指向,所以要传递二级指针。

相关推荐
你的电影很有趣15 分钟前
lesson68:JavaScript 操作 HTML 元素、属性与样式全指南
开发语言·前端·javascript
熊猫_豆豆24 分钟前
MATLAB画出湖面波纹相遇所形成的现象
开发语言·matlab·仿真
花心蝴蝶.1 小时前
Java 中的代理模式
java·开发语言·代理模式
风语者6661 小时前
perl踩坑系列=====正则表达式捕获
开发语言·perl
我科绝伦(Huanhuan Zhou)1 小时前
银河麒麟V10编译perl-5.42.0,并设置环境变量
开发语言·perl
大飞pkz1 小时前
【设计模式】享元模式
开发语言·设计模式·c#·享元模式
茉莉玫瑰花茶1 小时前
C++扩展 --- 并发支持库(补充3)
开发语言·c++
一只乔哇噻1 小时前
java后端工程师进修ing(研一版‖day49)
java·开发语言
枫叶丹41 小时前
【Qt开发】输入类控件(二)-> QTextEdit
开发语言·qt
JAVA学习通2 小时前
微服务项目->在线oj系统(Java-Spring)----[前端]
java·开发语言·前端