如何使由链接节点定义的堆栈的 pop() 函数正确返回其字符串值?

问题描述 投票:0回答:1

我正在做一个练习,要求我使用建立在链接节点上的堆栈,并且每个节点的值必须是字符串,而不是像平常那样的数字。

但是,我找不到用函数

pop()
返回字符串值的方法。换句话说,这似乎是一个未定义的行为,返回码为-1073741819(如果我没记错的话,它正在访问未分配的内存)

这是我使用堆栈的函数的代码:

typedef struct node{
    struct node* next;
    char value[];
}node;

typedef struct stack{
    node* top;
}stack;

char* res;

node* init_node(char c[])
{
    node* p = (node*)malloc(sizeof(node) + strlen(c) + 1);
    if (p == NULL) return NULL;
    strcpy(p->value, c); p->next = NULL;
    return p;
}

stack* init_stack()
{
    stack* s = (stack*)malloc(sizeof(stack));
    if (s == NULL) return NULL;
    s->top = NULL;
    return s;
}

int push(stack* *s, char c[])
{
    node* p = init_node(c);
    if (p == NULL) return -1;
    p->next = (*s)->top;
    (*s)->top = p;
    return 0;
}

bool isEmpty(stack* s)
{
    return (s->top == NULL);
}

const char* pop(stack* *s)
{
    if (!isEmpty(*s))
    {
        node* p = (*s)->top;
        strcpy(res, p->value);
        (*s)->top = p->next;
        free(p);
        return res;
    }
}

除了

pop()
之外,所有其他功能都运行良好。我曾经遇到过结构体中灵活字符串成员的内存分配问题,但这次我不认为它来自于此。

那么我应该如何编辑我的代码?

c string function linked-list stack
1个回答
0
投票

我正在做一个练习,要求我使用建立在链接节点上的堆栈,并且每个节点的值必须是字符串,而不是像平常那样的数字

堆栈只是节点的容器(可能是空的)。每个节点包含或指向某事物的一个单元,即数据记录。

那么我应该如何编辑我的代码?

恕我直言,发布的代码还有很多需要更改的地方。但为了工作

pop

必须改变,我将展示最小的改变,加上测试代码和结果

const char* pop(stack** s) { if (!isEmpty(*s)) { node* p = (*s)->top; strcpy(res, p->value); (*s)->top = p->next; free(p); return res; } }

    没有理由返回
  • const char*
    :正在从堆栈中提取数据,调用者可以对数据执行任何想要的操作。
  • s
     是一个输入值:将指针的地址传递到堆栈是没有意义的。更喜欢
    char* pop(Stack* )
    
    
  • res
     是个问题:
    res
     是什么鬼?没有理由依赖外部指针
考虑

char* pop(stack** s) { if (s == NULL) return NULL; if ((*s) == NULL) return NULL; if (isEmpty(*s)) return NULL; node* p = (*s)->top; char* res = malloc(1 + strlen(p->value)); strcpy(res, p->value); (*s)->top = p->next; free(p); return res; }
编辑代码

考虑常见的标头、代码和测试文件,如下所示

v0.h

#pragma once #include <stdbool.h> #include <stdlib.h> #include <string.h> typedef struct node { struct node* next; char value[]; } node; typedef struct stack { node* top; } stack; node* init_node(char[]); stack* init_stack(); int push(stack**, char[]); bool isEmpty(stack*); char* pop(stack**);

v0.c

#include "v0.h" node* init_node(char c[]) { node* p = (node*)malloc(sizeof(node) + strlen(c) + 1); if (p == NULL) return NULL; strcpy(p->value, c); p->next = NULL; return p; } stack* init_stack() { stack* s = (stack*)malloc(sizeof(stack)); if (s == NULL) return NULL; s->top = NULL; return s; } int push(stack** s, char c[]) { node* p = init_node(c); if (p == NULL) return -1; p->next = (*s)->top; (*s)->top = p; return 0; } bool isEmpty(stack* s) { return (s->top == NULL); } char* pop(stack** s) { if (s == NULL) return NULL; if ((*s) == NULL) return NULL; if (isEmpty(*s)) return NULL; node* p = (*s)->top; char* res = malloc(1 + strlen(p->value)); strcpy(res, p->value); (*s)->top = p->next; free(p); return res; }

main0.c
 测试一下

#include <stdio.h> #include "v0.h" char* factory(); int main(void) { char* el = NULL; stack* one = init_stack(); for (int i = 0; i < 8; i += 1) { el = factory(); int res = push(&one, el); printf("push() returned %d for '%s'\n", res, el); free(el); if (res != 0) return -1; } char* p = NULL; printf("\n\n Now pop() until error\n\n"); while ((p = pop(&one)) != NULL) printf("pop() returned '%s'\n", p); return 0; } char* factory() { // Element 1234567 static number = 1; char* value = malloc(16); if (value == NULL) return NULL; sprintf(value, "Element %7d", number); ++number; (number == 9999999) ? 1 : number + 1; return value; }
输出

push() returned 0 for 'Element 1' push() returned 0 for 'Element 2' push() returned 0 for 'Element 3' push() returned 0 for 'Element 4' push() returned 0 for 'Element 5' push() returned 0 for 'Element 6' push() returned 0 for 'Element 7' push() returned 0 for 'Element 8' Now pop() until error pop() returned 'Element 8' pop() returned 'Element 7' pop() returned 'Element 6' pop() returned 'Element 5' pop() returned 'Element 4' pop() returned 'Element 3' pop() returned 'Element 2' pop() returned 'Element 1'
    
© www.soinside.com 2019 - 2024. All rights reserved.