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

时间:2016-05-08 07:44:37

标签: 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(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;
}

当我打电话时的拳头     而(!空(myStack)) 它将我的数组中的值更改为1。

其次,每当我尝试以下内容时,我无法更改数组中的单个值:     (* stack_p).array [0] = value; 它不知道在内存中的哪个部分。 我希望有人能帮助我:))

3 个答案:

答案 0 :(得分:1)

我看到代码存在一些问题。

让我们执行push功能

(*stack_p).array = &value;

这将使array结构成员指向 local 变量value,并且一旦函数返回变量就不再存在,留下一个迷路指针并使用该指针将导致未定义的行为

该代码的第二个问题是你的堆栈只会(非法地)指向最后添加的元素。

您必须为array显式分配内存,并使用capacity来跟踪分配的内存量。使用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;
}

答案 1 :(得分:0)

不需要为stack_tt类型的20个结构分配空间,只需为一个结构分配空间:

stack_tt * newS = malloc(sizeof(stack_tt));

但是你需要为struct member array的元素分配空间:

newS->array = malloc( sizeof(int)*20);
newS->size = 0;
newS->capacity = 20;

现在您可以使用数组成员。

当你将值推送到'stack'时,你不应该用本地变量的地址覆盖数组成员,这没有意义,并且除了丢失先前分配的内存之外还会导致未定义的行为。而只是在函数array中将值分配给成员push

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

类似地,当您弹出元素时,从成员array获取当前元素:

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

其余的功能和代码应以相同的方式修复。

答案 2 :(得分: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_p).都可以替换为stack_p->,这更优雅。

newStack()malloc 20个结构中有点无用。你只需要一个。

然后你应该第一次malloc数组:

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