一.栈
栈:先进后出

1.1 内核栈
系统栈:操作系统自己管理的栈,先进后出
内核栈分为:满增栈 ,满减栈 ,空增栈 ,空减栈
1.1.1 满栈与空栈
满栈(full stack): 栈顶指针指向最后压入的数据,入栈时,栈顶指针先加(或者先减),再压入数据
空栈(empty stack): 栈顶指针指向下一次要入栈的位置,入栈时,先压入数据,栈顶指针再加(或者减)

1.1.2 增栈与减栈
增栈(ascending stack): 栈的生长方向由低地址到高地址
减栈(secending stack): 栈的生长方向由高地址到低地址

1.2 数据结构中的栈
栈: 数据结构中的一种线性存储结构,只允许从一端进行数据的插入与删除 的线性数据结构。
**特点:**先进后出。
**分类:**顺序栈:空间连续
链式栈:非连续空间
**应用:**网页

二. 栈的实现
2.1 栈的声明
cpp
typedef int DataType_t;
//栈节点
typedef struct stacknode{
DataType_t data;
struct stacknode *pnext;
}SNode_t;
//栈对象
typedef struct stack{
SNode_t *ptop;
int clen;
}Stack_t;
2.2 栈对象与节点的创建与判空
cpp
//创建栈对象
Stack_t *creat_stack()
{
Stack_t *pstack = malloc(sizeof(Stack_t));
if(pstack == NULL){
printf("malloc error\n");
return NULL;
}
pstack->ptop = NULL;
pstack->clen = 0;
return pstack;
}
//创建栈节点
SNode_t *creat_stack_node(DataType_t data)
{
SNode_t *psnode = malloc(sizeof(SNode_t));
if(psnode == NULL){
printf("malloc error\n");
return NULL;
}
psnode->data = data;
psnode->pnext = NULL;
return psnode;
}
//判断空栈
bool is_empty_stack(Stack_t *pstack)
{
return pstack->clen == 0;
}
2.3 入栈
cpp
//入栈
int stack_push(Stack_t *pstack, DataType_t data)
{
SNode_t *newnode = creat_stack_node(data);
if(pstack->ptop == NULL){
pstack->ptop = newnode;
}
else{
newnode->pnext = pstack->ptop;
pstack->ptop = newnode;
}
pstack->clen++;
return 0;
}
2.4 出栈
cpp
//出栈
int stack_pop(Stack_t *pstack, DataType_t *pdata)
{
if(is_empty_stack(pstack)){
return -1;
}
SNode_t *pfree = pstack->ptop;
pstack->ptop = pfree->pnext;
if(pdata){
*pdata = pfree->data;
}
free(pfree);
pfree = NULL;
pstack->clen--;
return 0;
}
2.5 获取栈顶元素
cpp
//获取栈顶元素
int get_stack_top(Stack_t *pstack, DataType_t *pdata)
{
if(is_empty_stack(pstack)){
return -1;
}
*pdata = pstack->ptop->data;
return 0;
}
2.6 遍历打印栈
cpp
//打印栈
void print_stack(Stack_t *pstack)
{
if(is_empty_stack(pstack)){
return;
}
SNode_t *cur = pstack->ptop;
while(cur){
printf("%d->",cur->data);
cur = cur->pnext;
}
printf("NULL\n");
}
2.7 销毁栈
cpp
//销毁栈
void destroy_stack(Stack_t **ppstack)
{
while(!is_empty_stack(*ppstack)){
stack_pop(*ppstack, NULL);
}
free(*ppstack);
*ppstack = NULL;
}
三. 有关malloc
cpp
char *p = malloc(100*sizeof(char));
......
对申请的空间的使用代码
......
free(p);
p = NULL;
在申请空间时,给了空间的大小,但是在释放空间时,却只传入了指针并没有传入要释放的空间的大小,为什么?
例如,当申请了100字节的空间,假设p指向的地址是 **0x56781234 ,**则在操作系统内部会维护一张表,里面记录了申请空间的初始地址与大小,如下图,在free时,操作系统内部去寻找相应的对应关系去释放申请的堆区内存。
另外,在对一段申请的堆区内存使用free释放时,最好在free之后对该指针置空,防止野指针
