我使用下面的代码使用数组实现堆栈
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
struct Stack{
int top;
int capacity;
int *array;
};
struct Stack *createStack()
{
struct Stack *stack=malloc(sizeof(struct Stack));
stack->top=-1;
stack->capacity=1;
stack->array=malloc(sizeof(sizeof(int)*stack->capacity));
}
void doubleStack(struct Stack *stack)
{
stack->capacity=stack->capacity*2;
stack->array=realloc(stack,stack->capacity);
}
void push( struct Stack *stack , int data)
{
if(stack->top==(stack->capacity)-1)
doubleStack(stack);
stack->array[++stack->top]=data;
}我的疑问是,一旦堆栈满了,当调用doubleStack时,是使用stack->array作为realloc()的第一个参数还是使用stack作为realloc()的第一个参数?
我认为stack->array应该通过。因为我们只需要重新分配内存的那一部分。
但我意外地通过了stack,这似乎也奏效了。请给我建议。
发布于 2015-08-19 12:21:09
您应该向realloc传递一个指向希望扩展的数组的指针。由于stack不是您希望扩展的数组,而stack->array是数组,所以您应该将stack->array作为第一个参数传递。
但是,您应该将realloc的结果存储在一个单独的变量中,并执行NULL检查。
如果函数未能分配请求的内存块,则返回一个空指针,并且参数ptr所指向的内存块不会被释放(它仍然有效,且其内容不变)。
否则,您可能会产生内存泄漏:
int *tmp = realloc(stack->array, stack->capacity);
if (tmp) {
stack->array = tmp;
} else {
... // Deal with the allocation error here
}发布于 2015-08-19 12:20:35
正如你正确的想法,
stack->array=realloc(stack,stack->capacity);至少应该是吗
stack->array=realloc(stack->array,stack->capacity);否则,如果成功,您将是free()-ing up stack本身,然后您将访问它。调用未定义行为。一旦你有了UB,很多东西就“看起来”起作用了。
也就是说,从使用的角度来看,
p = realloc(p, q); 代码类型非常糟糕,好像realloc()失败了一样,它不会修改作为参数传递的p,但是由于直接将realloc()的返回值赋值给p,p将被设置为NULL,从而丢失了实际存储的指针。
提示:始终使用临时指针收集realloc()的返回值,然后检查realloc()成功与否,如果realloc()成功,则将新返回的指针分配给传递给realloc()的指针。
发布于 2015-08-19 12:37:38
首先,函数push是错误的
void push( struct Stack *stack , int data)
{
if(stack->top==(stack->capacity)-1)
doubleStack(stack);
stack->array[++stack->top]=data;
}最初,top设置为1,capacity也设置为1。
所以这个条件
if(stack->top==(stack->capacity)-1)生成false和下面的语句
stack->array[++stack->top]=data;被处决了。它将写入超出分配数组的内存stack->array[2]。
我认为最初top应该设置为0。该函数的定义方式如下
void push( struct Stack *stack , int data )
{
if ( stack->top != stack->capacity || doubleStack( stack ) )
{
stack->array[stack->top++] = data;
}
}在这种情况下,您可以简单地定义一个函数,该函数以下列方式报告堆栈是否为空
int empty( struct Stack *stack ) { return stack->top == 0; }至于函数doubleStack,则应按以下方式定义
int doubleStack(struct Stack *stack)
{
int success = 0;
int new_capacity = 2 * stack->capacity;
int *tmp = = realloc( stack->array, new_capacity * sizeof( int ) );
if ( ( success = tmp != NULL ) )
{
stack->capacity = new_capacity;
stack->array = tmp;
}
return success
}考虑到我将函数的返回类型从void更改为int。此外,我还使用了一个中间变体new_capacity。如果重新分配失败,则不会更改当前容量。
https://stackoverflow.com/questions/32095311
复制相似问题