我正在做一个练习,要求我使用建立在链接节点上的堆栈,并且每个节点的值必须是字符串,而不是像平常那样的数字。
但是,我找不到用函数
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()
之外,所有其他功能都运行良好。我曾经遇到过结构体中灵活字符串成员的内存分配问题,但这次我不认为它来自于此。
那么我应该如何编辑我的代码?
我正在做一个练习,要求我使用建立在链接节点上的堆栈,并且每个节点的值必须是字符串,而不是像平常那样的数字
堆栈只是节点的容器(可能是空的)。每个节点包含或指向某事物的一个单元,即数据记录。
那么我应该如何编辑我的代码?恕我直言,发布的代码还有很多需要更改的地方。但为了工作
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'