【发布时间】:2014-10-02 13:45:57
【问题描述】:
当我的数组已满时,我在我的 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;
}
OUTPUT 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
【问题讨论】:
-
你应该用
c标记这个。 -
已编辑和标记。谢谢
-
它可以是
s->top = s->top + 1或(s->top)++(括号可选)。不是s->top=s->top++。
标签: c arrays stack double runtime-error