今天跑程序就实现了一个栈,写了个动态分配空间的代码,代码看来看去,都没发现问题,但是运行过程中却出问题了。
以下是纠正错误前的代码,也许是我不够细心,代码写的不够完善,但是咋看还是看不出啥问题的,大家也来看看。
错误代码如下:
#include "stdio.h"
#include "stdlib.h"
#include "string.h"
#define INIT_SIZE 100
#define INCREMENT 10
#define OK 1
#define ERROR 0
typedef int Status;
typedef int SElemType;
typedef struct Stack{
SElemType *base;
SElemType *top;
int stackSize;
}MyStack;
Status initStack(MyStack *p)
{
p->base = (SElemType *)malloc(sizeof(SElemType)*INIT_SIZE);
if(p->base == NULL)
{
return ERROR;
}
p->top=p->base;
p->stackSize = INIT_SIZE;
return OK;
}
/*getTop is not pop .*/
Status getTop(MyStack p,SElemType *e)
{
if(p.base == p.top)
{
return ERROR;
}
*e=*(p.top-1);
return OK;
}
Status push(MyStack *p,SElemType e)
{
if(p->top-p->base>=p->stackSize)
{
p->base = (SElemType *)realloc(p->base,sizeof(SElemType)*(INIT_SIZE+INCREMENT));
if(p->base == NULL)
{
return ERROR;
}
p->top = p->base + p->stackSize;
p->stackSize = p->stackSize+INCREMENT;
}
*p->top++ = e;
return OK;
}
Status pop(MyStack *p,SElemType *e)
{
if(p->top == p->base)
{
return ERROR;
}
*e = *(--p->top);
return OK;
}
Status destroy(MyStack *p)
{
if(p->base != NULL)
{
free(p->base);
}
p->stackSize =0;
p->top=NULL;
return OK;
}
int main()
{
MyStack *my;
int e;
initStack(my);
push(my,1);
push(my,2);
push(my,3);
pop(my,&e);
printf("%d ",e);
pop(my,&e);
printf("%d ",e);
pop(my,&e);
printf("%d ",e);
destroy(my);
return 0;
}
编译过程中出现如下问题:
Loaded 'ntdll.dll', no matching symbolic information found.
Loaded 'C:\WINDOWS\system32\kernel32.dll', no matching symbolic information found.
Unhandled exception in stack.exe:0xC0000005: Access Violation
通过分析可知这是内存访问越界的问题,应该编译器到某一个不知道的地方,去寻找相应的变量,这里
MyStack *my;
是一个未分配空间的指针,不能确定指针位置,因此如果我使用该指针的成员来分配空间,我就无法确定该空间分配在什么位置。就会找出内存访问越界的严重问题,可见一个小小的疏忽竟造成如此大的问题。
修改代码如下:
int main()
{
MyStack *my;
int e;
my =(MyStack *)malloc(sizeof(MyStack));
initStack(my);
push(my,1);
push(my,2);
push(my,3);
pop(my,&e);
printf("%d ",e);
pop(my,&e);
printf("%d ",e);
pop(my,&e);
printf("%d ",e);
destroy(my);
free(my);
return 0;
}
解决问题的方法,就是分配空间。有些时候编程时,注重逻辑结构的完整,忽视了一些细节,这样一些简单的问题,往往会困扰我们码农。因此以后再编程中遇到需要动态分配空间以及释放的问题,多留心多注意,把它当成一种习惯,这样可以减少不必要的低级错误。