news 2026/4/18 4:52:46

C 语言链表常见 10 大坑位(90% 初学者必踩)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
C 语言链表常见 10 大坑位(90% 初学者必踩)

链表本身不难,难的是:指针、内存、边界条件
下面这 10 个坑,基本覆盖初学者 90% 的崩溃现场。

坑 1:忘了给next置 NULL(野指针串链)

错误:

Node* n = malloc(sizeof(Node)); n->data = x; // n->next 未初始化

**后果:**遍历时跑飞、随机崩溃。

正确:

n->next = NULL;

坑 2:把“局部变量地址”当节点返回(悬空指针)

错误:

Node* create(int x) { Node n; // 栈变量 n.data = x; n.next = NULL; return &n; // 返回栈地址:函数结束就失效 }

**正确:**必须malloc

Node* create(int x){ Node* n = malloc(sizeof(Node)); n->data = x; n->next = NULL; return n; }

坑 3:忘了判空就解引用(*head 直接炸)

错误:

Node* cur = head; while (cur->next) { ... } // head 可能是 NULL

正确:

for (Node* cur=head; cur!=NULL; cur=cur->next) { ... }

坑 4:删除节点后继续用它(Use-After-Free)

错误:

free(cur); cur = cur->next; // cur 已释放,还在用

正确:

Node* next = cur->next; free(cur); cur = next;

坑 5:删除头节点没处理(头指针没更新)

**典型 bug:**删值命中第一个节点时,链表“看起来没变”。

正确思路:

  • 如果删的是头:*head = (*head)->next;

坑 6:插入/删除想改 head,却只传了Node* head(改不动)

错误:

void push_front(Node* head, int x) { Node* n = create(x); n->next = head; head = n; // 只改了形参 }

**正确:**传二级指针

void push_front(Node** head, int x){ Node* n = create(x); n->next = *head; *head = n; }

坑 7:遍历条件写错导致漏最后一个节点

错误:

while (cur->next != NULL) { printf("%d", cur->data); cur=cur->next; } // 最后一个没打印

正确:

while (cur != NULL) { ... }

坑 8:尾插没处理空链表(head==NULL)

错误:

Node* cur = head; // head 为 NULL while (cur->next) ...

正确:

if (*head == NULL) { *head = newNode; return; }

坑 9:内存泄漏(忘记 destroy / 只 free 头)

错误:

free(head); // 只释放了头,其余节点泄漏

正确:

while (head) { Node* next=head->next; free(head); head=next; }

坑 10:打印/调试把指针当 int(格式化输出错)

错误:

printf("%d\n", head); // 64位平台会错

正确:

printf("%p\n", (void*)head);

附:一份“安全版本”的链表骨架(建议你直接收藏)

typedef struct Node { int data; struct Node* next; } Node; Node* create_node(int x){ Node* n = (Node*)malloc(sizeof(Node)); if(!n) return NULL; n->data = x; n->next = NULL; return n; } void push_front(Node** head, int x){ Node* n = create_node(x); n->next = *head; *head = n; } void append(Node** head, int x){ Node* n = create_node(x); if(*head == NULL){ *head = n; return; } Node* cur = *head; while(cur->next) cur = cur->next; cur->next = n; } void destroy_list(Node* head){ while(head){ Node* next = head->next; free(head); head = next; } }
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/5 7:49:00

如何确认备份再生龙的版本

1、确认再生龙版本 打开客户备份的再生龙文件夹,找到以下文件clonezilla-img,用记事本打开 打开之后能看到以下信息 通过这个文件,可以看到镜像核心配置信息,它不仅记录了版本号,还包含完整的备份元数据。 2、详细信息 再生龙版本: clonezilla-live-20251017-questing…

作者头像 李华
网站建设 2026/4/18 11:18:42

30、文件系统空间信息与文件比较实用指南

文件系统空间信息与文件比较实用指南 1. 文件系统空间信息 在管理文件系统时,了解其空间使用情况至关重要。以下介绍两个常用的命令: df 和 du 。 1.1 df 命令 df 命令用于查看文件系统的整体空间信息,包括inode的使用情况。inode表在文件系统创建时就确定了大小…

作者头像 李华
网站建设 2026/4/18 11:20:09

Python+Django 核心介绍

PythonDjango 是一套主流的 Web 开发技术栈,其中 Django 是基于 Python 语言的开源高级 Web 框架,遵循 “MTV(Model-Template-View)” 架构(对应传统 MVC 架构),主打 “快速开发、开箱即用、安全…

作者头像 李华
网站建设 2026/4/18 9:40:12

49、技术编程知识综合解析

技术编程知识综合解析 1. 符号与运算符 特殊符号用途 :在编程和命令行操作中,许多特殊符号有着重要用途。例如, & 作为逻辑与运算符( && )用于逻辑判断, &= 是赋值运算符; * 在正则表达式中是元字符,同时也是算术运算符。 | 符号 | 用途 | …

作者头像 李华
网站建设 2026/4/18 9:41:04

企业选择小程序技术服务商的维度和模式解析

现今,微信小程序身为这般一种不用下载安装,只要点一下就能使用的轻量级应用,已然变成企业连通线上线下,去开展数字化经营的关键基础设施。跟着市场需求不断增长,好多技术服务商冒了出来,给企业提供从开发&a…

作者头像 李华
网站建设 2026/4/17 14:45:01

JAVA无人球杆柜:智能租赁新风尚

JAVA无人球杆柜通过物联网、AI与云原生架构的深度融合,以智能化、高效率、强安全的特性,重构了台球器材租赁的商业模式,成为推动行业升级的智能租赁新风尚。以下从技术架构、核心功能、用户体验、行业影响及未来展望五个维度展开分析&#xf…

作者头像 李华