我正在编写这个程序,它创建一个堆栈,推送和弹出值,然后删除堆栈并释放内存。我希望函数stack_push
将值推送到堆栈,如果堆栈已满,它将使内存量翻倍,基本上是重新分配内存并将其翻倍。在这种情况下,它应该从5个变量变为10个。然而,出于某种原因,它并没有这么做。我相信这个错误源于我试图重新分配内存,我做错了什么,我该如何修复它?
typedef struct stack
{
int capacity;
int size;
double *data;
} Stack;
Stack *ptr;
Stack *stack_create(void){
ptr = (Stack*)malloc(sizeof(Stack));
ptr->capacity = 5;
ptr->size = -1;
ptr->data = (double*)malloc(sizeof(double) * ptr->capacity);
return ptr;
}
void stack_push(Stack *s, double value){
if (s->size >= s->capacity-1){
ptr = (Stack *)realloc(ptr, 2*sizeof(Stack));
};
ptr->data[++ptr->size] = value;
}
int main(void)
{
// Create an empty stack.
Stack *s = stack_create();
for (int i = 0; i < 10; i++) {
stack_push(s, i);
}
return 0;
}
您正在重新分配一个额外的堆栈,而不是堆栈中的更多元素:
ptr = (Stack *)realloc(ptr, 2*sizeof(Stack));
你想要的是:
ptr->data = realloc(ptr->data, 2 * ptr->capacity * sizeof(double));
if (!ptr->data) {
perror("malloc failed");
exit(1);
}
ptr->capacity *= 2;
最后一行记录更新的容量,以便您知道何时需要再次重新分配。
请注意,您应该始终检查malloc
和realloc
的返回值,以确保内存已成功分配,并且不应该强制转换返回值,因为这可能会掩盖代码中的其他错误。
这篇文章强调了在学习时不阅读手册、常见问题解答和教科书的危险。我建议买一本K&R2e并在偶然发现它们时进行练习。
ptr = (Stack *)realloc(ptr, 2*sizeof(Stack));
首先,您使用的是C,而不是C++;您不应该强制转换realloc
的返回值。除了你对样板文件crud的期望之外,这可能不会引起任何头痛,但会引起头痛的是,如果你没有意识到ptr
的值可能会改变,并且由于传递值语义,这种改变只会在stack_push
的本地发生。此外,当ptr
确实发生了更改(但不适用于调用者(时,realloc
会使旧值无效,这会使调用者陷入这一行常见问题中。。。
明白我的意思了吗?从这一行代码中,我可以看到你的课本、大学课程等等都不太好用。有些事情需要改变。请🙏一定要考虑阅读K&R2e,并在可能的时候做这些练习。