LeetCode Line x: Char x: runtime error: member access within null pointer of type ‘struct ListNode

博客作者在解决LeetCode上的链表问题时遇到了因未检查空指针而导致的错误。他们通过百度搜索找到了问题的原因,并对代码进行了修改,确保在访问指针之前进行空指针检查。修复后的代码成功避免了运行时错误。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

今天做leetcode的时候使用链表遇到了这个问题,百思不得其解。遂疯狂百度标题,发现大伙都说了一个问题,那就是没有对指针判空。没办法,鄙人能力有限不知道为什么这个环境下不判空会报错,不过既然知道原因了就开始修改。

原代码如下,错误我圈起来了,因为没有对head和temp判断是否为空就开始访问,所以报错。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteDuplicates(struct ListNode* head){
    struct ListNode* ptr=head;
    struct ListNode* temp=NULL;
    struct ListNode* res=ptr;
    while(ptr->next!=NULL)
    {
        temp=ptr->next;
        while(temp->next!=NULL&&temp->val==ptr->val)
            temp=temp->next;
        if(temp->next==NULL)
            break;
        ptr->next=temp;
        ptr=ptr->next;
    }
    if(temp->val==ptr->val)
        ptr->next=NULL;
    else
        ptr->next=temp;
    return res;
}

修改后如下:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* deleteDuplicates(struct ListNode* head){
    if(head==NULL)
        return NULL;
    struct ListNode* ptr=head;
    struct ListNode* temp=NULL;
    struct ListNode* res=ptr;
    while(ptr->next!=NULL)
    {
        temp=ptr->next;
        while(temp->next!=NULL&&temp->val==ptr->val)
            temp=temp->next;
        if(temp->next==NULL)
            break;
        ptr->next=temp;
        ptr=ptr->next;
    }
    if(temp!=NULL&&temp->val==ptr->val)
        ptr->next=NULL;
    else
        ptr->next=temp;
    return res;
}

对即将要访问的指针进行判空后再操作就没问题啦.

 

鄙人菜鸟一枚,请忽视我的垃圾代码... 

 

<think>好的,用户现在遇到了另一个C语言的运行时错误,具体是在Line 20的Char 14处,提示“runtime error: member access within null pointer of type 'struct ListNode'”。这通常意味着用户试图访问一个空指针的结构体成员。我需要仔细分析这个问题,并给出清晰的解答步骤。 首先,我需要回忆之前的对话历史。用户之前的问题是关于变量未声明的错误,涉及链表操作中的指针访问错误。现在这个错误同样涉及链表的结构体指针,但这次的问题是在运行时发生的,说明用户可能在访问某个可能为空的指针的成员,比如val或next。 接下来,我需要确定可能的原因。常见的情况包括: 1. 在访问l1或l2的val或next成员时,其中一个指针已经是NULL。 2. 在循环中未正确检查指针是否为空,直接进行了访问。 3. 在创建新节点或移动指针时,没有正确处理NULL的情况。 然后,我需要考虑用户可能的代码结构。例如,用户可能在遍历链表时,假设l1或l2不为空,但实际其中一个可能已经遍历到末尾,导致指针为NULL。比如,在类似l1->val的代码中,如果l1已经是NULL,就会触发这个错误。 接下来,我需要给出具体的解决步骤。首先应该检查所有访问结构体成员的地方,确保指针不为空。例如,在循环中,每次访问l1->val之前,应该检查l1是否为NULL,否则使用默认值0。同样地,处理l2时也是如此。 然后,可能需要建议用户使用条件判断来安全访问指针,例如使用三元运算符:int val1 = (l1 != NULL) ? l1->val : 0;。这样即使l1或l2已经遍历完,也能避免访问空指针。 此外,用户可能在移动指针时没有检查next是否为NULL,导致下次循环时访问了NULL指针的成员。例如,在循环体内,如果l1已经为NULL,但代码仍然执行l1 = l1->next;,这会导致错误。正确的做法应该是在移动指针前检查当前指针是否非空,或者使用条件语句。 还需要提醒用户在创建新节点时,确保正确分配内存,并初始化next指针为NULL,避免悬空指针的问题。 最后,总结典型应用场景,比如LeetCode两数相加问题,用户可能在实现链表相加时,没有正确处理不同长度的链表或进位的情况,导致访问空指针。给出示例代码片段,帮助用户理解如何安全地访问结构体成员,并正确处理指针移动和进位。</think>### 一、错误现象解析 这个运行时错误表明代码中存在 **空指针成员访问**,具体场景为: ```c // 假设错误行类似: int val = l1->val; // 当l1为NULL时会触发此错误 ``` 根本原因是:在访问链表节点成员(如`val`或`next`)时,对应的指针(`l1`或`l2`)已经指向`NULL`。 --- ### 二、核心原因分析 #### 1. **链表遍历越界** - 当链表`l1`或`l2`已经遍历到末尾(即`next`指向`NULL`)时,仍然尝试访问其`val`或`next`成员 - 常见于循环条件设计不严谨,例如: ```c while (l1 != NULL || l2 != NULL) { // 错误:当l1或l2为NULL时仍可能执行l1->val sum = l1->val + l2->val; } ``` #### 2. **新节点未正确初始化** ```c struct ListNode* new_node = NULL; new_node->val = ...; // 访问未分配内存的指针 ``` --- ### 三、修正方案示范 #### 1. 安全访问成员的标准写法 ```c // 使用三元运算符防御空指针 int val1 = (l1 != NULL) ? l1->val : 0; // 若l1为空则取0 int val2 = (l2 != NULL) ? l2->val : 0; ``` #### 2. 循环条件的正确设计(以两数相加为例) ```c while (l1 != NULL || l2 != NULL || carry > 0) { // 安全取值 int val1 = (l1 != NULL) ? l1->val : 0; int val2 = (l2 != NULL) ? l2->val : 0; // 安全移动指针 if (l1 != NULL) l1 = l1->next; if (l2 != NULL) l2 = l2->next; } ``` #### 3. 创建新节点的正确方法 ```c struct ListNode* create_node(int val) { struct ListNode* node = malloc(sizeof(struct ListNode)); if (node == NULL) exit(1); // 内存分配失败处理 node->val = val; node->next = NULL; // 显式初始化next指针 return node; } ``` --- ### 四、典型应用场景 此错误常见于以下算法问题的链表操作中: #### LeetCode 2. 两数相加 - **关键逻辑**:同时遍历两个链表时,需处理长度不一致的情况 - **防御性编程要点**: $$ \text{当前值} = \begin{cases} l1\text{-}val & l1 \neq \text{NULL} \\ 0 & l1 = \text{NULL} \end{cases} + \begin{cases} l2\text{-}val & l2 \neq \text{NULL} \\ 0 & l2 = \text{NULL} \end{cases} + \text{carry} $$ --- ### 五、调试建议 1. **添加空指针检查** 在所有`->`操作符前插入断言: ```c assert(l1 != NULL); int val = l1->val; ``` 2. **打印指针状态** 在循环中输出指针地址: ```c printf("l1=%p, l2=%p\n", (void*)l1, (void*)l2); ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值