【发布时间】:2021-09-05 08:02:05
【问题描述】:
所以我在 c 中实现了一个堆栈。现在初始堆栈大小为 5,每次达到限制时我都会将其加倍。我把 1 到 20 的值压进去,然后一个一个弹出并打印出来。
这是输出: 20, 19, ..., 7, 0, 5, 4, 3, 2, 1
注意0 而不是6
这里是stack.c:
#define INITIAL_CAPACITY 5
struct Stack
{
int size; // initial size = 5
int *data; // dynamically allocated array
int pointer; // position of the top element
};
struct Stack *create_stack()
{
int *array = calloc(INITIAL_CAPACITY, sizeof(int));
struct Stack *stack = malloc(sizeof(struct Stack));
if (array == NULL || stack == NULL)
{
printf("Memory allocation failed in create_stack");
exit(EXIT_FAILURE);
}
stack->size = INITIAL_CAPACITY;
stack->data = array;
stack->pointer = -1;
return stack;
}
static void resize(struct Stack *stack)
{
const int new_size = stack->size * 2;
stack->data = realloc(stack->data, (sizeof *stack->data) * new_size);
if (stack->data == NULL)
{
printf("Memory allocation failed in the resize function.\n");
exit(EXIT_FAILURE);
}
stack->size = new_size;
}
void push(struct Stack *stack, int element)
{
int *stack_data = stack->data; // --> I think the bug is here
stack->pointer = stack->pointer + 1;
if (stack->pointer >= stack->size)
{
printf("Stack is full. Expanding the stack size.");
resize(stack);
}
assert(stack->pointer < stack->size);
stack_data[stack->pointer] = element;
}
但是当我将推送功能更改为此一切正常并且输出正确时:
void push(struct Stack *stack, int element)
{
stack->pointer = stack->pointer + 1;
if (stack->pointer >= stack->size)
{
printf("Stack is full. Expanding the stack size.");
resize(stack);
}
assert(stack->pointer < stack->size);
(stack->data)[stack->pointer] = element; // <--- changed line
}
现在输出如何正确? 发生了什么?
【问题讨论】:
-
什么是未公开的
resize?它会改变stack->data吗?请发帖Minimal, Reproducible Example。 -
int pointer;是一个令人困惑的名字......因为它不是一个指针。我建议将变量命名为size和capacity。请注意,如果一个calloc或malloc在create_stack中失败,您将泄漏另一个的内存。 -
@MikeCAT 我添加了 resize 和 create_stack 函数
-
resize可以更改stack->data的值。如果您使用保存在stack_data中的旧值,那将是一个问题。 -
永远不要这样做
pointer = realloc(pointer, ...)!重新分配可能会失败,然后在旧内存仍然有效的情况下返回一个空指针——但是您会通过覆盖指针而丢失对的引用,如果您没有另一个指针,则表示内存泄漏。更好:tmp = realloc(pointer, ...); if(tmp) { pointer = tmp; } else { /* some appropriate error handling */ }.
标签: c pointers stack undefined-behavior realloc