You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

C语言单链表栈pop函数问题求助:如何通过二级指针返回内存分配结果

解决单链表栈pop()函数的二级指针返回问题

我来帮你搞明白这个pop()函数的实现逻辑,核心就是利用二级指针来传递动态分配的内存地址——因为函数是void类型没法返回值,所以得通过指针的指针来修改外部变量的指向。

首先先明确栈的节点和栈结构的定义(假设你是这么定义的,如果不一样可以调整):

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

// 链表节点结构
typedef struct Node {
    char *data;       // 存储字符串数据
    struct Node *next;// 指向下一个节点
} Node;

// 栈结构,只需要记录栈顶节点
typedef struct {
    Node *top;
} STACK;

接下来是pop()函数的具体实现,每一步我都加了注释:

void pop(STACK *stack, char **name) {
    // 先处理非法输入或空栈的情况
    if (stack == NULL || stack->top == NULL) {
        *name = NULL;  // 空栈时返回NULL
        return;
    }

    // 1. 取出栈顶节点
    Node *top_node = stack->top;

    // 2. 为要返回的字符串分配内存
    // 计算字符串长度,+1是为了存储字符串结束符'\0'
    size_t str_len = strlen(top_node->data);
    *name = (char *)malloc(str_len + 1);
    
    // 3. 检查内存分配是否成功(非常重要,避免空指针操作)
    if (*name == NULL) {
        fprintf(stderr, "Error: Failed to allocate memory in pop()\n");
        *name = NULL;
        // 即使分配失败,也要清理栈顶节点避免内存泄漏
        free(top_node->data);
        free(top_node);
        stack->top = top_node->next;
        return;
    }

    // 4. 将栈顶节点的字符串拷贝到新分配的内存中
    strcpy(*name, top_node->data);

    // 5. 更新栈顶指针,弹出当前栈顶节点
    stack->top = top_node->next;

    // 6. 释放栈顶节点的内存(包括节点内的字符串数据)
    // 这里要和你的push()逻辑匹配:如果push时是拷贝字符串到节点,就可以放心释放;如果是直接存指针,就不能释放!
    free(top_node->data);
    free(top_node);
}

关键知识点解释

  • 为什么要用char **name
    如果用char *name,函数收到的只是外部指针的副本,你在函数里修改这个副本的指向,外部的指针根本不会变。而char **传递的是指针的地址,通过*name就能直接修改外部指针的指向,让它指向我们在函数里分配的内存。

  • 使用时的注意事项:
    调用pop()后,拿到的name是动态分配的内存,一定要在外部手动free,不然会造成内存泄漏!比如:

    int main() {
        STACK my_stack = {NULL};
        // 假设你有push函数,比如push(&my_stack, "Tom"); push(&my_stack, "Jerry");
    
        char *popped_name = NULL;
        pop(&my_stack, &popped_name);
        
        if (popped_name != NULL) {
            printf("弹出的元素:%s\n", popped_name);
            free(popped_name);  // 必须释放!
        } else {
            printf("栈为空\n");
        }
    
        return 0;
    }
    
  • 和push()函数的配合:
    一定要保证push()pop()的内存管理逻辑一致。比如push()的时候应该把输入的字符串拷贝到节点的data里(而不是直接存指针),这样pop()的时候才能安全释放top_node->data,避免野指针问题。

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

火山引擎 最新活动