C:堆栈元素被函数调用覆盖

C:堆栈元素被函数调用覆盖,c,C,我在做学校作业,我遇到了两个问题。我必须用数组模拟堆栈。 我目前的代码如下: #include <stdlib.h> #include <stdio.h> typedef struct { int capacity; int * array; int size; } stack_tt; int pop(stack_tt * stack_p); void push(stack_tt * stack_p, int value); int top(st

我在做学校作业,我遇到了两个问题。我必须用数组模拟堆栈。 我目前的代码如下:

#include <stdlib.h>
#include <stdio.h>

typedef struct {
    int capacity;
    int * array;
    int size;
} stack_tt;
int pop(stack_tt * stack_p);
void push(stack_tt * stack_p, int value);
int top(stack_tt * stack_p);
stack_tt * newStack(void);
int empty(stack_tt * stack_p);

int main() {
    stack_tt * myStack = newStack();
    push(myStack, 123);
    push(myStack, 99);
    push(myStack, 4444);
    while (!empty(myStack)) {
        int value;
        value = pop(myStack);
        printf("popped: %d\n", value);
    }
    return 0; }

stack_tt * newStack(){
    stack_tt * newS = malloc(sizeof(stack_tt) * 20);
    (*newS).capacity = 1;
    (*newS).size = 0;
    return newS;
}

void push(stack_tt * stack_p, int value){
    if ((*stack_p).size >= (*stack_p).capacity) {
        (*stack_p).capacity*=2;
        //realloc(stack_p, stack_p->capacity * sizeof(stack_tt));
    }
    (*stack_p).array = &value;
    (*stack_p).size++;
}

int pop(stack_tt * stack_p){
    (*stack_p).size--;
    int fap = *(*stack_p).array;
    return fap;
}

int empty(stack_tt * stack_p){
    if ((*stack_p).size >= 1)
        return 0;
    return 1;
}
#包括
#包括
类型定义结构{
国际能力;
int*数组;
整数大小;
}stack_tt;
int pop(stack_tt*stack_p);
无效推送(stack_tt*stack_p,int值);
int top(堆栈_tt*堆栈_p);
stack_tt*新闻标题(无效);
int空(stack_tt*stack_p);
int main(){
stack_tt*myStack=newStack();
推(myStack,123);
推(myStack,99);
推(myStack,4444);
而(!empty(myStack)){
int值;
值=pop(myStack);
printf(“弹出:%d\n”,值);
}
返回0;}
stack_tt*newStack(){
stack_-tt*newS=malloc(sizeof(stack_-tt)*20);
(*新闻)。容量=1;
(*新闻)。大小=0;
返回消息;
}
无效推送(stack_tt*stack_p,int值){
如果((*堆栈p).size>=(*堆栈p).capacity){
(*堆栈p).容量*=2;
//realloc(stack_p,stack_p->容量*sizeof(stack_tt));
}
(*stack_p).array=&value;
(*stack_p).size++;
}
int pop(stack_tt*stack_p){
(*堆栈大小--);
int fap=*(*堆栈p).array;
返回fap;
}
int空(stack_tt*stack_p){
如果((*堆栈p).size>=1)
返回0;
返回1;
}
首先,当我打电话的时候 而(!empty(myStack)) 它将数组中的值更改为1

其次,每当我尝试以下操作时,我无法更改数组中的单个值: (*stack_p).array[0]=值; 它不知道在记忆中的什么地方可以看。
我希望有人能帮助我:)

没有必要为20个类型为
stack\u tt
的结构分配空间,您只需要为一个结构分配空间:

stack_tt * newS = malloc(sizeof(stack_tt));
但是,您需要为结构成员数组的元素分配空间:

newS->array = malloc( sizeof(int)*20);
newS->size = 0;
newS->capacity = 20;
现在可以使用数组成员


将值推送到“堆栈”时,不应使用局部变量的地址覆盖数组成员,这是没有意义的,除了丢失先前分配的内存外,还会导致未定义的行为。相反,只需在函数
push
中将值分配给成员
array

stack_p->array[stack_p->size] = value;
stack_p->size++;

类似地,当弹出一个元素时,从成员
数组中获取当前元素:

stack_p->size--;
int fap = stack_p->array[stack_p->size];

其余的函数和代码应该以相同的方式修复。

在我看来,代码有几个问题

让我们在需要的地方使用
push
功能

(*stack_p).array = &value;
这将使
数组
结构成员指向局部变量
,一旦函数返回,变量就不再存在,留下一个错误的指针,使用该指针将导致未定义的行为

该代码的第二个问题是,堆栈将只(非法)指向添加的最后一个元素

必须为
数组
明确分配内存,并使用
容量
跟踪分配的内存量。使用
size
作为分配数组的索引,用于推送和弹出。差不多

stack_tt * newStack(){
    stack_tt * newS = malloc(sizeof(stack_tt));  // Only allocate *one* structure
    newS->capacity = 0;  // Start with zero capacity
    newS->size = 0;
    newS->array = NULL;
    return newS;
}

void push(stack_tt * stack_p, int value){
    if (stack_p->size + 1 > stack_p->capacity){
        // Increase capacity by ten elements
        int new_capacity = stack_p->capacity + 10;
        int * temp_array = realloc(stack_p->array, new_capacity * sizeof(int));
        if (temp_srray == NULL)
            return;

        stack_p->capacity = new_capacity;
        stack_p->array = temp_array;
    }

    stack_p->array[stack_p->size++] = value;
}

int pop(stack_tt * stack_p){
    if (stack_p->size > 0)
        return stack_p->array[--stack_p->size];
    return 0;
}

int empty(stack_tt * stack_p){
    return stack_p->size == 0;
}

您的代码很好,但可能您不了解realloc的用法:

//realloc(stack_p, stack_p->capacity * sizeof(stack_tt));
此函数返回指向新分配内存的指针,如果请求失败,则返回NULL

realloc
(如函数所示)获取您传递的指针指向的内存,将该内存块复制到一个新的调整大小的块中。所以正确的代码应该是

stack_p->array = realloc(stack_p->array, stack_p->capacity * sizeof(stack_tt));
另一行是错误的:

(*stack_p).array = &value;
更改为:

stack_p->array[stack_p->size] = value;
另一个小建议是,每个
(*stack\u p)。
都可以被
stack\u p->
替换,这更优雅

newStack()。你只需要一个

然后您应该第一次
malloc
阵列:

newS->array = malloc(sizeof(int));
newS->capacity = 1;

我尝试过这个,我给了我一个错误:'thread1:EXC_BAD_ACCESS(code=1,address=0x0)'@Klopper当然,我指出的例子并不是唯一的问题。不可能指出每个错误,因为代码在概念上是错误的。整个项目将不得不重写。使用我给出的例子作为指导。谢谢,我现在明白了:)这是一个很大的帮助!
(*stack\u p)有什么问题。
他为什么要使用
stack\u p->
?最后一个的好处是什么?它只是一个更优雅的代码。优雅代码==可读性更强且易于理解的代码当涉及指针时,优雅代码和可读性更强的代码之间没有区别。请您接受
int pop()
中的以下编辑:
if(stack\u p->size>0)
。否则它会一直挂在无限循环中
弹出:0
。我没有足够的代表来做这件事。谢谢