当数组已满时,我在doublestack()函数中使用realloc()将其加倍。这样做超过两次会给我一个运行时错误。我认为这可能是因为原始堆栈(使用create()函数创建的)的大小仍然相同,所以我也将其加倍,从而消除了运行时错误。
我的问题:
这到底是怎么回事?每次将数组加倍时,堆栈是否需要加倍?
如果是这样,为什么原始堆栈首先能够支持对doublestack()的第一次和第二次调用?
您能否给我一个图形/内存映射的解释,以解释我们在realloc()数组和堆栈时到底发生了什么?
我是在浪费记忆吗?有没有更好的方法来使用数组实现堆栈?
感谢您的宝贵时间。
代码和输出:(取消注释,表示UNCOMMENT使用realloc()将堆栈大小加倍
#include <stdio.h>
#include <stdlib.h>
#define INIT_CAPACITY 1
struct stack
{
int top;
int capacity;
int *array;
};
struct stack * create(int);
void push(struct stack *,int);
int top(struct stack *);
int isfull(struct stack *);
int isempty(struct stack *);
void traverse(struct stack *);
struct stack *doublestack(struct stack *);
int pop(struct stack *);
int main()
{
struct stack *S=create(INIT_CAPACITY);
push(S,1);
push(S,2);//First call to doublestack()
push(S,3);//Second call to doublestack()
push(S,4);
push(S,5);//Third call to doublestack() - ERROR
traverse(S);
}
struct stack * create(int capacity)//create a new stack with INIT_CAPACITY
{
struct stack *newstack=(struct stack *)malloc(sizeof(struct stack));
if(!newstack) return NULL;
newstack->top=-1;
newstack->capacity=capacity;
newstack->array=(int *)malloc(sizeof(int)*(newstack->capacity));
return newstack;
}
void push(struct stack *s,int data)
{
printf("\nCurrent stack is");
traverse(s);
printf("\nPushing %d onto stack:\n\n",data);
if(isfull(s))
{
printf("\nStack is FULL.Now doubling...\n\n");
doublestack(s);
}
(s->top)++;
s->array[s->top]=data;
}
struct stack * doublestack(struct stack *s)//using realloc()
{
s=realloc(s,(sizeof(struct stack)*2));//**UNCOMMENT THIS TO ELIMINATE ERROR**
s->capacity *= 2;
s->array=realloc(s->array,s->capacity);
}
void traverse(struct stack *s)
{
printf("\n");
int i;
for(i=0;i <= s->top;i++)
{
printf("%d\t",s->array[i]);
}
printf("\n\n");
}
int top(struct stack *s)
{
return s->array[s->top];
}
int isfull(struct stack *s)
{
return (s->capacity)-1==s->top;
}
int isempty(struct stack *s)
{
return s->top==-1;
}
int pop(struct stack *s)
{
if(isempty(s))
{
printf("\nStack is EMPTY\n\n");
return 0;
}
int data=s->array[s->top];
s->top--;
return data;
}
输出1 :(没有堆栈加倍,因此有运行时错误)
Current stack is
Pushing 1 onto stack:
Current stack is
1
Pushing 2 onto stack:
Stack is FULL.Now doubling...
Current stack is
1 2
Pushing 3 onto stack:
Stack is FULL.Now doubling...
Current stack is
1 2 3
Pushing 4 onto stack:
Current stack is
1 2 3 4
Pushing 5 onto stack:
Stack is FULL.Now doubling...
*** glibc detected *** ./a.out: realloc(): invalid next size: 0x09191018 ***
======= Backtrace: =========
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x70f01)[0xb75e5f01]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(+0x7660d)[0xb75eb60d]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(realloc+0xdd)[0xb75eb8ed]
./a.out[0x8048674]
./a.out[0x804861c]
./a.out[0x8048569]
/lib/i386-linux-gnu/i686/cmov/libc.so.6(__libc_start_main+0xe6)[0xb758be46]
./a.out[0x8048421]
======= Memory map: ========
08048000-08049000 r-xp 00000000 08:07 549947 /home/user/a.out
08049000-0804a000 rw-p 00000000 08:07 549947 /home/user/a.out
09191000-091b2000 rw-p 00000000 00:00 0 [heap]
b7400000-b7421000 rw-p 00000000 00:00 0
b7421000-b7500000 ---p 00000000 00:00 0
b7546000-b7562000 r-xp 00000000 08:07 548 /lib/i386-linux-gnu/libgcc_s.so.1
b7562000-b7563000 rw-p 0001b000 08:07 548 /lib/i386-linux-gnu/libgcc_s.so.1
b7574000-b7575000 rw-p 00000000 00:00 0
b7575000-b76d1000 r-xp 00000000 08:07 468 /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b76d1000-b76d2000 ---p 0015c000 08:07 468 /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b76d2000-b76d4000 r--p 0015c000 08:07 468 /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b76d4000-b76d5000 rw-p 0015e000 08:07 468 /lib/i386-linux-gnu/i686/cmov/libc-2.13.so
b76d5000-b76d8000 rw-p 00000000 00:00 0
b76e8000-b76eb000 rw-p 00000000 00:00 0
b76eb000-b76ec000 r-xp 00000000 00:00 0 [vdso]
b76ec000-b7708000 r-xp 00000000 08:07 504 /lib/i386-linux-gnu/ld-2.13.so
b7708000-b7709000 r--p 0001b000 08:07 504 /lib/i386-linux-gnu/ld-2.13.so
b7709000-b770a000 rw-p 0001c000 08:07 504 /lib/i386-linux-gnu/ld-2.13.so
bfb34000-bfb55000 rw-p 00000000 00:00 0 [stack]
Aborted
输出2 :(堆栈加倍且无错误)
Current stack is
Pushing 1 onto stack:
Current stack is
1
Pushing 2 onto stack:
Stack is FULL.Now doubling...
Current stack is
1 2
Pushing 3 onto stack:
Current stack is
1 2 3
Pushing 4 onto stack:
Current stack is
1 2 3 4
Pushing 5 onto stack:
1 2 3 4 5
s->capacity
将项目数存储在堆栈中。每个项目的大小为sizeof(int)
。第二对Arg的realloc的是多少字节,就像malloc
。
s->array=realloc(s->array,s->capacity);
你要
s->array=realloc(s->array, s->capacity * sizeof(int));
或更笼统地说
s->array = realloc(s->array, s->capacity * sizeof(*(s->array)));
另外,您应该检查的返回值realloc
并处理发生的任何错误。
这段代码是胡说八道:
s=realloc(s,(sizeof(struct stack)*2));//**UNCOMMENT THIS TO ELIMINATE ERROR**
首先,如果realloc
决定移动数组,则不会将新数组返回s
给调用方。但更重要的是,您需要调整数组的大小,而不是调整数组周围的元数据。巧合的是,取消注释该行隐藏了问题。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句