首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

c语言malloc之后再realloc的有关问题

2012-04-05 
c语言malloc之后再realloc的问题不才学习严蔚敏的数据结构C语言版堆栈一课时,参考书上的内容自己编写的一

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所指内存区域,同时返回新分配的内存区域的首地址。即重新分配存储器块的地址。

[解决办法]
探讨

e=*--s.top;
按照书上这一句,我认为作者这句代码的意思也认为空间是连续的.大家觉得呢.

[解决办法]
分配给你的同一个空间内一定连续,但多个空间之间就不一定了
[解决办法]
不可能,动态分配的空间一定是连续的啊
在入栈时,有一句写错了
 s->top=s->base+s->stacksize*sizeof(stackelem);
应为: s->top++;
[解决办法]
难道不会单步调试查看内存啊?

内存有问题,基本上就是在realloc的时候top多+了导致使用非法内存
if(stacklength(s)>=s->stacksize)
把=去掉大概就可以了,这个问题很容易重现,自己单步一下不就什么都知道了?

热点排行