在pop()函数中,我正在尝试更改最后一个全局变量的值。它在 push(n) 函数中工作正常,而在 pop() 函数中,它在函数内更改它(使用 prints 验证它),但在离开该方法后重置为以前的值。无法理解它。
#include "stack.h"
#include <stdio.h>
#include <stdlib.h>
int *Stack;
int Last = -1;
void make_empty( void ){
free(Stack);
Last = -1;
Stack = NULL;
//Stack = malloc(4);
return;
}
int is_empty( void ){
if (Last == -1)
return 1;
return 0;
}
int top( void ){
if (is_empty()) {
printf("La pila è vuota");
}
return Stack[Last];
}
int pop( void ){
if (is_empty()) {
printf("La pila è vuota");
return 0;
}
int temp = Stack[Last];
printf("last: %dn", Last);
Stack = realloc(Stack, (--Last+1)*sizeof(int));
printf("last: %dn", Last);
return temp;
}
void push( int n ){
Stack = realloc(Stack, (++Last+1)*sizeof(int));
Stack[Last] = n;
return;
}
void print_stack( void ){
printf("last: %dn", Last);
for (int c=0; c<=Last; c++)
printf("%d ", Stack[c]);
printf("n");
}
您没有为堆栈分配足够的空间。
开始时Last
为 -1。 然后将一个元素推送到堆栈并分配空间:
Stack = realloc(Stack, ++Last*sizeof(int));
增量后,Last
为 0。 因此,您正在分配0*sizeof(int) == 0
字节。 然后你写信给不存在Stack[Last]
。 这会调用未定义的行为,在您的情况下,该行为表现为在您不期望时导致变量更改。
由于Last
包含最后一个有效索引,因此您希望将 1 添加到此索引以获取要分配的适当数量的元素:
Stack = realloc(Stack, (++Last + 1)*sizeof(int));
弹出时会犯类似的错误:
Stack = realloc(Stack, --Last*sizeof(int));
您还需要在此处添加 1:
Stack = realloc(Stack, (--Last + 1)*sizeof(int));
堆栈的实现包含未定义的行为。
例如,最初Last
等于-1
。
int Last = -1;
然后在push
操作中
void push( int n ){
Stack = realloc(Stack, ++Last*sizeof(int));
Stack[Last] = n;
return;
}
分配的内存大小等于0
,因为++Last
等于0
。您不能更改分配的大小等于0
的内存。
方法pop
也存在类似的问题。当Last
等于0
则在此语句中
Stack = realloc(Stack, --Last*sizeof(int));
表达式--Last
等于-1
由于操作数的类型sizeof(int)
而转换为类型size_t
的最大值。
例如,您可以通过以下方式编写方法push
void push( int n ){
Stack = realloc(Stack, ( ++Last + 1 ) *sizeof(int));
Stack[Last] = n;
return;
}
在您可以使用的pop
方法
if ( Last == 0 )
{
free( Stack );
Stack = NULL;
}
else
{
Stack = realloc(Stack, ( Last *sizeof(int));
}
--Last;
注意这个if语句
if ( Last == 0 )
{
free( Stack );
Stack = NULL;
}
当堆栈为空时,必须释放所有分配的内存,并且必须将Stack
设置为NULL
。