You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

双向链表代码出现指针访问违规错误的问题排查请求

排查双向链表实现中的指针访问违规问题

错误直接原因

触发访问违规的核心原因是传入了指向未初始化堆内存的野指针,代码中pstan的值为0xCDCDCDCD(Visual Studio环境下未初始化堆内存的标记值),导致尝试访问pstan->data时触发内存访问错误。

具体问题分析

1. 新节点的指针未初始化

使用malloc创建Node时,仅设置了data字段,但prev和next指针未初始化,默认是堆内存的随机垃圾值(非NULL)。后续判断pstan->prev != NULL或pstan->next != NULL时,会误将垃圾值当作有效指针,触发递归调用传入野指针。

2. Assort函数的分支条件错误

在cur->data >= pstan->data的分支中,递归判断条件错误地写成了pstan->prev != NULL,正确逻辑应该是判断pstan->next != NULL,否则会错误地往prev方向递归,而非预期的next方向。

3. 插入节点时未维护双向链表的指针关系

当将新节点挂载到目标节点的prev或next时,仅设置了目标节点的指针,未同步设置新节点的对应指针(比如pstan->prev = cur后,未设置cur->next = pstan和cur->prev = NULL),导致链表指针不完整,后续操作出现异常。

4. 函数形参的值传递误区

Assort函数中pstan = cur是修改函数内部的形参,不会影响main函数中pStan变量的值。不过main函数后续通过pStan = pRoot修正了这个问题,未引发直接错误,但需要注意C语言参数传递的特性。

修正后的代码

#include <stdio.h>
#include <stdlib.h>

struct Node {
    int data;
    struct Node* prev;
    struct Node* next;
};

struct Node* pRoot = NULL;

void Inorder(struct Node* root) {
    if (root == NULL) {
        return;
    }
    // 先遍历左(prev)侧
    Inorder(root->prev);
    printf("%d ", root->data);
    // 再遍历右(next)侧
    Inorder(root->next);
}

void Assort(struct Node* cur, struct Node* pstan) {
    if (pRoot == NULL) {
        pRoot = cur;
        // 初始化根节点的双向指针为NULL
        cur->prev = NULL;
        cur->next = NULL;
    } else {
        if (cur->data < pstan->data) {
            if (pstan->prev == NULL) {
                // 将cur挂载到pstan的prev位置
                pstan->prev = cur;
                cur->next = pstan;
                cur->prev = NULL;
            } else {
                // 递归往前找合适位置
                Assort(cur, pstan->prev);
            }
        } else {
            if (pstan->next == NULL) {
                // 将cur挂载到pstan的next位置
                pstan->next = cur;
                cur->prev = pstan;
                cur->next = NULL;
            } else {
                // 递归往后找合适位置
                Assort(cur, pstan->next);
            }
        }
    }
}

int main() {
    struct Node* pStan = NULL;

    for (int i = 0; i < 5; i++) {
        struct Node* Current = (struct Node*)malloc(sizeof(struct Node));
        printf("정수를 입력하세요.\n");
        scanf("%d", &Current->data);

        Assort(Current, pStan);
        pStan = pRoot;
    }

    Inorder(pRoot);
    return 0;
}

修正点说明

  • 新增了Inorder函数的空指针判断,避免传入NULL时触发错误。
  • 创建新节点后,在Assort函数中初始化根节点的prev和next为NULL,非根节点挂载时同步维护双向指针关系。
  • 修正了Assort函数中递归分支的条件错误,确保往正确的方向递归查找插入位置。
  • 移除了不必要的调试语句,简化逻辑。

内容的提问来源于stack exchange,提问作者ty par

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 06:45:00