leetcode55 报错Line 9: Char 18: runtime error: store to null pointer of type 'int' (solution.c)

本文详细解析了LeetCode上的经典问题“跳跃游戏”。通过一个非负整数数组,每个元素代表当前位置可跳跃的最大长度,判断是否能到达最后一个位置。提供了C语言的解决方案,并修复了代码中因指针使用不当导致的错误。

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

leetcode55跳跃游戏,题目描述 :

给定一个非负整数数组,你最初位于数组的第一个位置。

数组中的每个元素代表你在该位置可以跳跃的最大长度。

判断你是否能够到达最后一个位置。

示例 1:

输入: [2,3,1,1,4]

输出: true

解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。

代码

bool canJump(int* nums, int numsSize){
    int* index;
    int jump = 0;
    int max_index;

    if (nums == NULL || numsSize == 0)
        return false;
    for (int i = 0; i < numsSize; i++) {
        index[i] = i + nums[i];
    }
    max_index = index[0];

    while (jump < numsSize && jump <= max_index) {
        if (max_index < index[jump])
            max_index = index[jump];
        jump++;
    }

    if (jump == numsSize)
        return true;
    
    return false;
}

执行代码报错提示:

因为指针地址指向函数内的局部变量,在函数退出时,该变量的存储空间会被销毁,此时去访问该地址就会出现这个错误。

解决方法:

改用数组定义

int index[numsSize + 1];

完整代码如下:

bool canJump(int* nums, int numsSize){
    int index[numsSize + 1];
    int jump = 0;
    int max_index;

    if (nums == NULL || numsSize == 0)
        return false;
    for (int i = 0; i < numsSize; i++) {
        index[i] = i + nums[i];
    }
    max_index = index[0];

    while (jump < numsSize && jump <= max_index) {
        if (max_index < index[jump])
            max_index = index[jump];
        jump++;
    }

    if (jump == numsSize)
        return true;
    
    return false;
}

 

<think>好的,用户现在遇到了另一个C语言的运行时错误,具体是在Line 20的Char 14处,提示“runtime error: member access within null pointer of type &#39;struct ListNode&#39;”。这通常意味着用户试图访问一个空指针的结构体成员。我需要仔细分析这个问题,并给出清晰的解答步骤。 首先,我需要回忆之前的对话历史。用户之前的问题是关于变量未声明的错误,涉及链表操作中的指针访问错误。现在这个错误同样涉及链表的结构体指针,但这次的问题是在运行时发生的,说明用户可能在访问某个可能为空的指针的成员,比如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); ```
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值