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

栈Push操作为何引发段错误?如何保留双指针TOS修正出错代码?

栈Push操作引发段错误的原因及你的代码问题解析

咱们一步步来拆解你的问题,先解决通用的Push段错误原因,再针对性看你的代码问题~

首先回答第一个问题:为什么栈的Push操作会引发段错误?
常见的触发原因主要有这几个:

  • 解引用空指针/野指针:比如栈顶指针没正确初始化,或者指向了无效内存区域,当你尝试访问这个指针指向的内容时,操作系统会直接抛出段错误
  • 内存分配失败:如果用链表实现栈,调用malloc/calloc时可能因内存不足返回NULL,这时候直接访问新节点的成员(比如temp->num)就会触发错误
  • 数组栈溢出:如果用固定大小的数组实现栈,当Push的元素数量超过数组长度时,会越界访问内存,同样会引发段错误

接下来看你的代码为什么会出现段错误,同时满足你保留TOS作为双指针的需求:

你的代码核心问题

先看main函数里的这行定义:

NODE **TOS = NULL, *temp;

你定义了一个双指针TOS并初始化为NULL,然后直接把它传给push函数。但push函数需要的是一个指向有效NODE指针的双指针——也就是说,这个双指针得指向一个实际存在的NODE*变量,这样push才能通过它修改栈顶指针的指向。

而你现在传的是一个NULL的双指针,当push里执行temp->next = (*TOS)或者(*TOS) = temp时,本质是在对NULL指针进行解引用,这是完全非法的内存访问,操作系统直接就会触发段错误。

保留双指针的修正方案

如果你一定要保留TOS作为双指针,只需要让它指向一个有效的NODE*变量即可,下面是修正后的完整代码:

#include<stdio.h> 
#include<stdlib.h> 
typedef struct node_tag{ 
    int num; 
    struct node_tag* next; 
}NODE; 

void push(int x, NODE **TOS){ 
    NODE* temp = (NODE*) malloc(sizeof(NODE)); 
    // 一定要检查malloc是否成功!避免内存分配失败导致的段错误
    if(temp == NULL){
        fprintf(stderr, "内存分配失败!\n");
        exit(EXIT_FAILURE);
    }
    temp->num = x; 
    temp->next = (*TOS); 
    (*TOS) = temp; 
} 

int main(){ 
    // 先定义一个普通的栈顶指针,初始化为NULL
    NODE *top_ptr = NULL;
    // 让双指针TOS指向这个普通指针
    NODE **TOS = &top_ptr; 
    printf("<<<Stack Push>>>");
    push(0, TOS); 
    printf("%i", (*TOS)->num); 

    // 别忘了释放内存,避免内存泄漏
    NODE* temp = *TOS;
    *TOS = (*TOS)->next;
    free(temp);
    return 0;
}

更常规的写法(同样符合双指针传参逻辑)

其实日常写链表栈时,大部分情况会直接在main里定义普通的栈顶指针,然后传它的地址给push函数,本质和上面的逻辑一致,只是少了一层双指针的显式定义:

#include<stdio.h> 
#include<stdlib.h> 
typedef struct node_tag{ 
    int num; 
    struct node_tag* next; 
}NODE; 

void push(int x, NODE **TOS){ 
    NODE* temp = (NODE*) malloc(sizeof(NODE)); 
    if(temp == NULL){
        fprintf(stderr, "内存分配失败!\n");
        exit(EXIT_FAILURE);
    }
    temp->num = x; 
    temp->next = (*TOS); 
    (*TOS) = temp; 
} 

int main(){ 
    NODE *TOS = NULL; 
    printf("<<<Stack Push>>>");
    // 传普通指针的地址,也就是NODE**类型
    push(0, &TOS); 
    printf("%i", TOS->num); 

    // 释放内存
    NODE* temp = TOS;
    TOS = TOS->next;
    free(temp);
    return 0;
}

最后再提个醒:任何时候调用malloc都要检查返回值,不然遇到内存不足的情况,你的代码还是会触发段错误哦~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:09:10