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

基于双向链表的栈反转函数中使用第二个栈报错求助

问题分析与代码修正

你的代码存在几处关键错误,以下是具体分析和修正方案:

核心错误点

  1. reverse_s函数栈指针初始化错误:Stack *s2 = stack_init;试图把Stack类型的常量直接赋值给Stack*指针,类型完全不匹配,会导致编译报错。
  2. pop函数缺少栈空的返回逻辑:当栈为空时pop没有返回语句,会触发未定义行为。
  3. 内存分配失败未处理:create_node和reverse_s中没有处理malloc失败的情况,代码健壮性不足。

修正后的完整代码

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

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

//---------------------Stack---------------------

typedef struct Stack {
    int size;
    Node* head;
    Node* tail;
    int top;
} Stack;

const Stack stack_init = { .size = 0, .head = NULL, .tail = NULL, .top = -1 };

Node* create_node(int elm) {
    Node* node = malloc(sizeof * node);
    if (!node) {
        perror("Failed to allocate node");
        return NULL;
    }
    node->data = elm;
    node->prev = NULL;
    node->next = NULL;
    return node;
}

int is_empty_s(Stack *s) {
    return s->tail == NULL;
}

void push(Stack *s, int elm) {
    Node* updated_head = create_node(elm);
    if (!updated_head) return; // 处理节点创建失败
    if (!s->head) {
        s->head = updated_head;
        s->tail = s->head;
    } else {
        updated_head->next = s->head;
        s->head->prev = updated_head;
        s->head = updated_head;
    }
    s->size++;
    s->top = s->head->data;
}

int pop(Stack *s) {
    if (is_empty_s(s)) {
        fprintf(stderr, "Error: Stack is empty, cannot pop\n");
        return -1; // 栈空时返回-1作为错误标记
    }
    Node* node = s->head;
    int elm = node->data;
    s->head = s->head->next;
    if (s->head) {
        s->head->prev = NULL;
        s->top = s->head->data;
    } else {
        s->tail = NULL;
        s->top = -1;
    }
    s->size--;
    free(node);
    return elm;
}

Stack* reverse_s(Stack *s) { 
    // 动态分配栈内存,避免函数结束后栈变量销毁
    Stack *s2 = malloc(sizeof(Stack));
    if (!s2) {
        perror("Failed to allocate stack");
        return NULL;
    }
    // 用初始化常量填充新栈的初始状态
    *s2 = stack_init;
    
    while (!is_empty_s(s)) {
        int val = pop(s);
        if (val != -1) {
            push(s2, val);
        }
    }
    return s2;
}

// 新增打印栈的函数,用于验证结果
void print_stack(Stack *s) {
    Node* curr = s->head;
    printf("Stack (top to bottom): ");
    while (curr) {
        printf("%d ", curr->data);
        curr = curr->next;
    }
    printf("\n");
}

int main() {
    Stack s1 = stack_init;
    push(&s1, 5);
    push(&s1, 4);
    printf("Original ");
    print_stack(&s1);
    
    Stack* reversed_stack = reverse_s(&s1);
    if (reversed_stack) {
        printf("Reversed ");
        print_stack(reversed_stack);
        // 释放反转栈的内存:先释放所有节点,再释放栈结构体
        while (!is_empty_s(reversed_stack)) {
            pop(reversed_stack);
        }
        free(reversed_stack);
    }
    return 0;
}

关键修改说明

  1. reverse_s栈初始化修正:

    • 用malloc(sizeof(Stack))在堆上分配栈内存,确保返回的指针在函数外部依然有效。
    • 通过*s2 = stack_init将初始化常量的所有字段复制到新栈中,保证初始状态正确。
  2. pop函数补全返回逻辑:

    • 栈空时打印错误信息并返回-1,避免未定义行为。
  3. 增强健壮性:

    • 在create_node和reverse_s中添加malloc失败的错误提示和处理。
    • push函数中判断节点创建是否成功,避免空指针操作。
  4. 新增验证工具:

    • 添加print_stack函数方便查看栈内容,main函数中演示了反转后的结果输出和内存释放流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 17:55:42