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

使用strcpy构建BST触发SIGSEGV错误,请求排查问题

二叉搜索树(BST)编写中的SIGSEGV错误排查

问题概述

编写二叉搜索树(BST)并尝试按顺序打印树结构时,使用strcpy填充节点触发了SIGSEGV错误。Valgrind检测出两个问题:大小为8的未初始化值使用,以及对地址0x0的无效写入操作。

Valgrind报错信息

==104951== Memcheck, a memory error detector
==104951== Copyright (C) 2002-2022, and GNU GPL'd, by Julian Seward et al.
==104951== Using Valgrind-3.20.0 and LibVEX; rerun with -h for copyright info
==104951== Command: ./bst.o
==104951== 
==104951== Use of uninitialised value of size 8
==104951==    at 0x484975C: strcpy (vg_replace_strmem.c:558)
==104951==    by 0x40115A: main (in /home/lukaswsantos/Documents/algorithms/bst.o)
==104951== 
==104951== Invalid write of size 1
==104951==    at 0x484975C: strcpy (vg_replace_strmem.c:558)
==104951==    by 0x40115A: main (in /home/lukaswsantos/Documents/algorithms/bst.o)
==104951==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==104951== 
==104951== 
==104951== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==104951==  Access not within mapped region at address 0x0
==104951==    at 0x484975C: strcpy (vg_replace_strmem.c:558)
==104951==    by 0x40115A: main (in /home/lukaswsantos/Documents/algorithms/bst.o)
==104951==  If you believe this happened as a result of a stack
==104951==  overflow in your program's main thread (unlikely but
==104951==  possible), you can try to increase the size of the
==104951==  main thread stack using the --main-stacksize= flag.
==104951==  The main thread stack size used in this run was 8388608.
==104951== 
==104951== HEAP SUMMARY:
==104951==     in use at exit: 0 bytes in 0 blocks
==104951==   total heap usage: 0 allocs, 0 frees, 0 bytes allocated
==104951== 
==104951== All heap blocks were freed -- no leaks are possible
==104951== 
==104951== Use --track-origins=yes to see where uninitialised values come from
==104951== For lists of detected and suppressed errors, rerun with: -s
==104951== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
fish: Job 1, 'valgrind  ./bst.o' terminated by signal SIGSEGV (Address boundary error)

问题代码

#include "stdio.h"
#include "string.h"

struct node {
    char data[255];
    struct node *node_left;
    struct node *node_rigth 
};

int number = 0;
int pointer = 0;

const char *NODE_0 = "node 0";


int main (int number, struct node *leaf, struct node *tree) {
    struct node node_zero;
    strcpy(node_zero.node_left->data, NODE_0);

    return 0;
}

错误分析

  • main函数参数不符合标准:C语言标准main函数的参数应为int argc, char *argv[],自定义的参数number、leaf、tree未被初始化,会导致未定义行为,这也是Valgrind检测到“未初始化值使用”的原因之一。
  • 空指针访问:node_zero是栈上分配的结构体,其成员node_left指针未初始化,默认是随机垃圾值(此处恰好为0x0即空指针)。直接通过node_zero.node_left->data访问空指针的成员,会触发无效写入,最终导致SIGSEGV。
  • 结构体定义语法错误:struct node中node_rigth成员末尾缺少分号,这会导致编译警告或错误。

修正后的代码示例

基础修复版本

先正确初始化当前节点的数据,后续扩展二叉搜索树逻辑时再为左右节点分配内存:

#include "stdio.h"
#include "string.h"

struct node {
    char data[255];
    struct node *node_left;
    struct node *node_right;  // 修正拼写和分号
};

const char *NODE_0 = "node 0";

// 标准main函数参数
int main(int argc, char *argv[]) {
    struct node node_zero;
    // 直接初始化当前节点的data,而非未初始化的左节点
    strcpy(node_zero.data, NODE_0);
    // 初始化左右指针为NULL,避免野指针
    node_zero.node_left = NULL;
    node_zero.node_right = NULL;

    printf("节点数据:%s\n", node_zero.data);
    return 0;
}

带左节点分配的版本

如果需要创建左节点,需先为其分配内存:

#include "stdio.h"
#include "string.h"
#include "stdlib.h"  // 引入malloc相关头文件

struct node {
    char data[255];
    struct node *node_left;
    struct node *node_right;
};

const char *NODE_0 = "node 0";
const char *NODE_LEFT = "left node";

int main(int argc, char *argv[]) {
    struct node node_zero;
    strcpy(node_zero.data, NODE_0);
    // 为左节点分配内存
    node_zero.node_left = (struct node*)malloc(sizeof(struct node));
    if (node_zero.node_left == NULL) {
        perror("malloc failed");
        return 1;
    }
    // 初始化左节点的数据和指针
    strcpy(node_zero.node_left->data, NODE_LEFT);
    node_zero.node_left->node_left = NULL;
    node_zero.node_left->node_right = NULL;

    printf("根节点:%s\n", node_zero.data);
    printf("左节点:%s\n", node_zero.node_left->data);

    // 记得释放分配的内存
    free(node_zero.node_left);
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 19:27:09