c语言malloc之后再realloc的问题
不才学习严蔚敏的数据结构C语言版堆栈一课时,参考书上的内容自己编写的一个堆栈的程序,遇到了下面的怪问题.
程序如下(用vc++6.0环境)
stack.cpp:
- C/C++ code
#include <stdio.h>#include <stdlib.h>#include "../Status.h"#define STACK_INIT_SIZE 5 //堆栈初始大小#define STACKINCREMENT 5 //堆栈满之后再增加的大小typedef char *stackelem;typedef struct{ stackelem *base,*top; int stacksize;}sqstack;/*------堆栈基本操作-------*/Status initstack(sqstack *s){ s->base=(stackelem *)malloc(STACK_INIT_SIZE*sizeof(stackelem)); if(!s->base) exit(OVERFLOW); s->top=s->base; s->stacksize=STACK_INIT_SIZE; return OK;}Status stackempty(sqstack *s){ if(s->base==s->top) return TRUE; return FALSE;}Status gettop(sqstack *s,stackelem *e){ if(stackempty(s)) { e=NULL; printf("取栈顶失败:堆栈为空!\n"); return ERROR; } e=s->top-sizeof(stackelem); return OK;}int stacklength(sqstack *s){ if(stackempty(s)) return 0; else return (s->top-s->base)/sizeof(stackelem);}Status push(sqstack *s,stackelem e){ if(stacklength(s)>=s->stacksize) { printf("堆栈已满,增加空间\n"); s->base=(stackelem *)realloc(s->base,(s->stacksize+STACKINCREMENT)*sizeof(stackelem)); if(!s->base) { printf("增加空间失败,压栈失败,程序退出!\n"); exit(OVERFLOW); } s->top=s->base+s->stacksize*sizeof(stackelem); s->stacksize+=STACKINCREMENT; } *(s->top)=e; s->top+=sizeof(stackelem); printf("元素 %s 压栈成功!\n",e); return OK;}Status pop(sqstack *s,stackelem e){ if(stackempty(s)) { printf("出栈失败:栈为空!\n"); return ERROR; } s->top-=sizeof(stackelem); e=*(s->top); /* *(s->top)=NULL ;*/ printf("元素 %s 出栈成功!\n",e); return OK;}Status clearstack(sqstack *s){ stackelem e; while(!stackempty(s)) pop(s,e); printf("堆栈已经清空\n"); return OK;}Status destroystack(sqstack *s){ clearstack(s); free(s->base); printf("堆栈已经销毁\n"); return OK;}Status printstack(sqstack *s){ printf("开始打印堆栈...\n\n"); if(stackempty(s)) { printf("打印错误:没有可以打印的内容!\n"); printf("\n打印堆栈结束.\n"); return ERROR; } stackelem *p=s->top; while((p>s->base)) { p-=sizeof(stackelem); //我认为malloc之后不管realloc多少次,如果没有失败,得到的空间应该是连续的,所以这样写 printf("\t%s\n",*p); } printf("\n打印堆栈结束.\n"); return OK;}void main(){ sqstack s; stackelem e; initstack(&s);/* push(&s,"2"); printstack(&s); clearstack(&s); printstack(&s);*/ push(&s,"1"); push(&s,"2"); push(&s,"3"); push(&s,"4"); push(&s,"5"); push(&s,"6"); push(&s,"7"); push(&s,"8"); push(&s,"9"); push(&s,"10"); push(&s,"11this is just for test"); push(&s,"12this is just for test"); push(&s,"13"); push(&s,"14 this for test"); push(&s,"15"); push(&s,"16"); push(&s,"17"); push(&s,"18"); printstack(&s); pop(&s,e); pop(&s,e); pop(&s,e); pop(&s,e); pop(&s,e); printstack(&s); destroystack(&s); }Status.h的内容如下:
- C/C++ code
#define TRUE 1#define FALSE 0#define OK 1#define ERROR 0#define INFEASIBLE -1#define OVERFLOW -2typedef int Status;
问题是:
1,如果我将堆栈初始大小STACK_INIT_SIZE设为100的时候,程序能正常运行,且printstack()能正常显示堆栈内容.
2.如果将堆栈初始大小STACK_INIT_SIZE设为5的时候,程序(共压入18次)不能正常显示堆栈内容
只能显示后面realoc中增加的元素内容,第一次malloc的元素不能显示.
还会报错弹出对话框"程序遇到问题需要关闭",点调试没有反映
我乃初学者,如果什么地方肤浅了,还请多多包含,不吝赐教.
期盼能得到解决,先谢谢大家了
[解决办法]
realloc
功能:先按照newsize指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来mem_address所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。
[解决办法]
[解决办法]
分配给你的同一个空间内一定连续,但多个空间之间就不一定了
[解决办法]
不可能,动态分配的空间一定是连续的啊
在入栈时,有一句写错了
s->top=s->base+s->stacksize*sizeof(stackelem);
应为: s->top++;
[解决办法]
难道不会单步调试查看内存啊?
内存有问题,基本上就是在realloc的时候top多+了导致使用非法内存
if(stacklength(s)>=s->stacksize)
把=去掉大概就可以了,这个问题很容易重现,自己单步一下不就什么都知道了?