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

比较int时触发Read access violation问题排查求助

Read Access Violation 问题诊断与修复

你的代码中触发Read Access Violation的核心原因是二叉树和链表的根指针初始化错误,导致insert函数访问了未初始化的垃圾内存。以下是具体分析和修复方案:

核心错误点

  1. 二叉树根指针初始化错误
    在main函数中,你用struct treeNode *tree = malloc(size * sizeof(struct treeNode));分配了一块内存,但二叉树的根指针应该初始化为NULL——insert函数的逻辑是当node == NULL时创建新节点,而malloc返回的未初始化内存不是NULL,导致insert进入非空分支时,node指向无效内存,访问node->num直接触发读访问违规。

  2. 链表头指针初始化错误
    同理,struct listNode *list = malloc(size * sizeof(struct listNode));也是错误的,链表头指针必须初始化为NULL,否则newNode函数在更新链表时会操作垃圾内存,引发后续访问错误。

次要问题(需同步修复)

  • LOAD函数中用atol(tmp)将字符串转为long,但insert的参数是int,可能导致整数溢出,建议改用atoi(tmp)。
  • SCAN和LOAD中分配的字符数组未释放,存在内存泄漏。
  • printList函数循环条件错误:若链表为空,tmp->next会触发空指针访问;且当前逻辑会跳过第一个节点,应改为while (tmp != NULL)。
  • main函数的参数名写反了:标准写法是int argc, char *argv[],你写成了int argv, char *argc[],虽然不影响运行,但不符合规范。
  • 缺少内存分配和文件打开的错误检查,容易忽略潜在问题。

修复后的完整代码

// Garrett Manley

// delete these when turning it in
#pragma warning(disable : 4996)

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

// define structs
struct treeNode {
    int num;
    struct treeNode *right, *left;
};

struct listNode {
    struct treeNode *tNode; // data is a pointer to the tree
    struct listNode *next;
};

// creates and returns a new node with given data, also adds node to linked list 
struct treeNode *newNode(int data, struct listNode **list) {
    // make tree node
    struct treeNode *node = malloc(sizeof(struct treeNode));
    if (!node) {
        perror("malloc treeNode failed");
        exit(EXIT_FAILURE);
    }
    node->num = data;
    node->left = NULL;
    node->right = NULL;
    // make list node
    struct listNode *newListNode = malloc(sizeof(struct listNode));
    if (!newListNode) {
        perror("malloc listNode failed");
        free(node);
        exit(EXIT_FAILURE);
    }
    newListNode->tNode = node;
    newListNode->next = *list;
    *list = newListNode;

    return node;
}

// inserts given node into the tree in sorted order
struct treeNode *insert(struct treeNode *node, int data, struct listNode **list) {
    if (node == NULL) { // if the tree is empty return new node
        return newNode(data, list);
    } else { // if there is a node use recursion to get to the bottom of the tree and add a node in the right spot
        if (data <= node->num) {
            node->left = insert(node->left, data, list);
        } else {
            node->right = insert(node->right, data, list);
        }
        return node; // return the (unchanged) node pointer
    }
}

// print linked list
void printList(struct listNode *list) {
    struct listNode *tmp = list;
    while (tmp != NULL) {
        printf("%d ", tmp->tNode->num);
        tmp = tmp->next;
    }
    printf("\n");
}

// skim through the file and find how many entries there are
int SCAN(FILE *stream) {
    int size = 0;
    char *str = malloc(100 * sizeof(char));
    if (!str) {
        perror("malloc str failed");
        exit(EXIT_FAILURE);
    }
    while (fgets(str, 100, stream) != NULL) {
        // 去除换行符并跳过空行
        str[strcspn(str, "\n")] = '\0';
        if (strlen(str) > 0) {
            size++;
        }
    }
    free(str);
    return size;
}

// loop through the file and load the entries into the main data array
void LOAD(FILE *stream, int size, struct treeNode **tree, struct listNode **list) {
    rewind(stream);
    char *tmp = malloc(100 * sizeof(char));
    if (!tmp) {
        perror("malloc tmp failed");
        exit(EXIT_FAILURE);
    }
    int count = 0;
    while (count < size && fgets(tmp, 100, stream) != NULL) {
        str[strcspn(tmp, "\n")] = '\0';
        if (strlen(tmp) == 0) continue;
        *tree = insert(*tree, atoi(tmp), list);
        count++;
    }
    free(tmp);
}

// 递归释放二叉树节点
void freeTree(struct treeNode *node) {
    if (node == NULL) return;
    freeTree(node->left);
    freeTree(node->right);
    free(node);
}

// 释放链表节点
void freeList(struct listNode *list) {
    struct listNode *tmp;
    while (list != NULL) {
        tmp = list;
        list = list->next;
        free(tmp);
    }
}

// free up everything
void FREE(struct treeNode *tree, struct listNode *list) {
    freeList(list);
    freeTree(tree);
}

int main(int argc, char *argv[]) {
    FILE *file = fopen("./hw7.data", "r");
    if (!file) {
        perror("Failed to open hw7.data");
        exit(EXIT_FAILURE);
    }

    int size = SCAN(file);

    struct treeNode *tree = NULL;
    struct listNode *list = NULL;

    LOAD(file, size, &tree, &list);
    
    // print linked list
    printList(list);

    FREE(tree, list);
    fclose(file);
    
    return 0;
}

关键修复说明

  • 将tree和list初始化为NULL,符合insert和newNode的逻辑预期。
  • 增加了malloc、fopen的错误检查,避免静默失败。
  • 修正了main函数的参数名,符合C语言规范。
  • 实现了freeTree和freeList函数,避免内存泄漏。
  • 处理文件输入时跳过空行,避免无效数据转换。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 23:45:41