C、全局变量更改不保留在函数之外



在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

相关内容

  • 没有找到相关文章

最新更新