简体   繁体   English

C,全局变量更改不会保留在 function 之外

[英]C, Global Variable change isn't kept outside the function

In the pop() function i am trying to change the value of the Last global variable.在 pop() function 中,我试图更改 Last 全局变量的值。 It works fine in the push(n) function, while in the pop() one it changes it inside the function (verifying it with prints) but then it resets to the previous value just after leaving the method.它在 push(n) function 中工作正常,而在 pop() 中,它在 function 内更改它(通过打印验证它),但在离开方法后它会重置为以前的值。 Can't get my head around it.我无法理解它。

#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: %d\n", Last);
    Stack = realloc(Stack, (--Last+1)*sizeof(int));
    printf("last: %d\n", Last);
    return temp;
}

void push( int n ){
    Stack = realloc(Stack, (++Last+1)*sizeof(int));
    Stack[Last] = n;
    return;
}

void print_stack( void ){
    printf("last: %d\n", Last);
    for (int c=0; c<=Last; c++)
        printf("%d ", Stack[c]);
    printf("\n");
}

The implementation of the stack contains undefined behavior.堆栈的实现包含未定义的行为。

For example initially Last is equal to -1 .例如最初Last等于-1

int Last = -1;

then in the push operation然后在push操作中

void push( int n ){
    Stack = realloc(Stack, ++Last*sizeof(int));
    Stack[Last] = n;
    return;
}

there is allocated memory of the size equal to 0 because ++Last is equal to 0 .由于++Last等于0 ,因此分配了大小等于0的 memory 。 You may not change the memory allocated with the size equal to 0 .您不能更改分配的大小等于0的 memory 。

A similar problem exists for the method pop .方法pop也存在类似的问题。 When Last is equal to 0 then in this statementLast等于0时,则在此语句中

Stack = realloc(Stack, --Last*sizeof(int));

the expression --Last is equal -1 that is converted to the maximum value of the type size_t due to the type of the operand sizeof(int) .由于操作数sizeof(int)的类型,表达式--Last等于-1转换为size_t类型的最大值。

You could write for example the method push the following way例如,您可以通过以下方式编写方法push

void push( int n ){
    Stack = realloc(Stack, ( ++Last + 1 ) *sizeof(int));
    Stack[Last] = n;
    return;
}

And in the pop method you could usepop方法中你可以使用

if ( Last == 0 ) 
{
    free( Stack );
    Stack = NULL;
}
else
{
    Stack = realloc(Stack, ( Last *sizeof(int));
}

--Last;

Pat attention to this if statement注意这个 if 语句

if ( Last == 0 ) 
{
    free( Stack );
    Stack = NULL;
}

when the stack is empty all allocated memory must be freed and Stack must be set to NULL .当堆栈为空时,所有分配的 memory 必须被释放并且Stack必须设置为NULL

You're not allocating enough space for your stack.您没有为堆栈分配足够的空间。

At the start Last is -1.开始时Last是 -1。 Then you push an element to the stack and allocate space:然后你将一个元素压入堆栈并分配空间:

Stack = realloc(Stack, ++Last*sizeof(int));

After the increment, Last is 0. So you're allocating 0*sizeof(int) == 0 bytes.增量后, Last为 0。因此您分配0*sizeof(int) == 0个字节。 You then write to Stack[Last] which doesn't exist.然后您写入不存在的Stack[Last] This invokes undefined behavior , which in your case manifests by causing a variable to change when you don't expect.这会调用未定义的行为,在您的情况下,这会在您不期望时通过导致变量发生变化来表现出来。

Since Last contains the last valid index, you want to add 1 to this to get the proper number of elements to allocate:由于Last包含最后一个有效索引,因此您希望向其添加 1 以获得要分配的正确数量的元素:

Stack = realloc(Stack, (++Last + 1)*sizeof(int));

You make a similar mistake when popping:弹出时您会犯类似的错误:

Stack = realloc(Stack, --Last*sizeof(int));

You also need to add 1 here:您还需要在此处添加 1:

Stack = realloc(Stack, (--Last + 1)*sizeof(int));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM