在实现栈的通用性过程中遇到的问题(段错误)
先上代码
seqstack.h
#ifndef STACK_H
#define STACK_H
#include <stdbool.h>
// 该程序模块提供栈的功能
// 默认处理的是int数据
// 用户如需处理其他自定义数据,请定义如下宏,如:
// #define SEQSTACK_NODE xxx
// 如果用户没有自定义顺序栈元素类型
// 那么类型默认为int
#ifndef SEQSTACK_NODE
#define SEQSTACK_NODE int
#endif
typedef SEQSTACK_NODE datatype;
// 顺序栈的管理结构体
typedef struct seqstack
{
int size;
int top;
datatype *data;
}stack;
// 以下是栈的操作接口
// 初始化
// size: 初始状态下,空栈的容量
stack * init_stack(int size);
// 入栈
// 成功返回真,失败(当栈已满的时候)返回假
bool push(stack *s, datatype data);
// 出栈: 将栈顶元素删除
// 成功返回真,失败(当栈为空的时候)返回假
bool pop(stack *s);
// 读取栈顶: 将栈顶元素返回
bool top(stack *s, datatype *pdata);
// 判断满
bool full(stack *s);
// 判断空
bool empty(stack *s);
#endif
seqstack.c
#include <time.h>
#include <errno.h>
#include <stdio.h>
#include <fcntl.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>
#include <strings.h>
#include <stdbool.h>
#include <pthread.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include "seqstack.h"
// 栈的初始化
// 成功时,返回栈的管理结构体指针
// 失败时,返回NULL
stack * init_stack(int size)
{
// 申请栈的管理结构体
stack * s = malloc(sizeof(stack));
if(s != NULL)
{
s->size = size;
s->top = -1;
s->data = calloc(size, sizeof(datatype));
if(s->data == NULL)
{
free(s);
return NULL;
}
}
return s;
}
// 入栈: 将数据data,置入栈s的栈顶中
bool push(stack *s, datatype data)
{
// 栈已满,无法置入
if(full(s))
return false;
s->data[++s->top] = data;
return true;
}
// 出栈: 将栈顶元素删除
bool pop(stack *s)
{
if(empty(s))
return false;
s->top--;
return true;
}
// 取栈顶元素
bool top(stack *s, datatype *pdata)
{
if(empty(s))
return false;
*pdata = s->data[s->top];
return true;
}
// 判断栈是否已满、是否为空
bool empty(stack *s)
{
return s->top == -1;
}
bool full(stack *s)
{
return s->top == s->size-1;
}
//使用默认参数测试代码、程序正常执行 OK
test.c
#include <stdio.h>
#include "seqstack.h"
int main(void)
{
stack *s = init_stack(10);
push(s, 1);
push(s, 2);
push(s, 3);
push(s, 4);
push(s, 5);
// 应该输出54321
int c;
while(!empty(s))
{
top(s, &c);
printf("%d", c);
pop(s);
}
printf("\n");
return 0;
}
通过以上你以为程序没有bug吗?
再看看使用一下代码测试(自定义类型参数)
test_char.c
#include <stdio.h>
#define SEQSTACK_NODE char
#include "seqstack.h"
int main(void)
{
stack *s = init_stack(10);
push(s, 'a');
push(s, 'b');
push(s, 'c');
push(s, 'd');
push(s, 'e');
// 应该输出edcba
char c;
while(!empty(s))
{
top(s, &c);
printf("%c", c);
pop(s);
}
printf("\n");
return 0;
}
以上代码似乎没有什么错误,但是这会产生段错误。
下面分析一下段错误产生的原因及解决方法:
![在这里插入图片描述](https://img-blog.csdnimg.cn/20200511083156719.bmp?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L0xHV1hVUA==,size_16,color_FFFFFF,t_70)
总结一下:seqstack.c 与test_char.c 的数据类型不同,导致段错误
解决方法:将seqstack.c 的代码放置到seqstack.h,即将它们合为1个.h 文件即可。并将函数声明为static,因为static函数才能在头文件中定义实现。
缺点:无法将.h文件变为动态库。
如有不对,恳请指正!