我正在创建堆栈
typedef struct cool {
int value;
}arr;
typedef struct stack {
int top;
arr **st;
}STACK;
我需要通过一次增加一个块来创建STACK dynamicall。所以我尝试了这样..
int size = 1;
STACK *mainstack;
mainstack = (STACK *) malloc (sizeof(STACK));
create(mainstack);
create(mainstack);
create(mainstack);
void create(STACK *mainstack) {
if((mainstack = realloc(mainstack, (size + 1))) != NULL) {
mainstack[size].st = (arr **) malloc(10 * sizeof(arr*));
}
++size;
}
我第一次调用create()没有问题..但是我再次通过调用create()重新分配我得到这样的错误... realloc():下一个大小无效.....
所以我改变了
的reallocmainstack = realloc(mainstack, (size + 1) * sizeof(STACK));
然后我再次得到这样的错误..
malloc():内存损坏很快
两次我叫做创造它的工作好。但是aftrer第三次调用显示错误.. 请有人告诉我这些背后究竟是什么?或者没有任何其他方法来实现我的想法而不会出现这些错误..
答案 0 :(得分:1)
这不起作用:
void create(STACK *mainstack){
if ((mainstack = realloc(mainstack, (size + 1))) != NULL) {
mainstack[size].st = (arr **)malloc(10 * sizeof(arr*));
}
++size;
}
mainstack = realloc(mainstack...
修改本地变量mainstack
,该变量将超出函数末尾的范围。
因此,在create(mainstack);
之后,mainstack
将保持不变。
简单示例:
void foo(int bar)
{
bar = 2;
}
...
int x = 123;
foo(x);
// x contains 123 and n ot 2
例如,你需要这个:
STACK *create(STACK *mainstack){
if ((mainstack = realloc(mainstack, (size + 1))) != NULL) {
mainstack[size].st = (arr **)malloc(10 * sizeof(arr*));
}
++size;
return mainstack;
}
int main()
{
int size = 1;
STACK *mainstack;
mainstack = malloc(sizeof(STACK));
mainstack = create(mainstack);
mainstack = create(mainstack);
mainstack = create(mainstack);
}
也就是说,使用全局变量size
的整体设计不是很好,create
中的错误处理很糟糕。
答案 1 :(得分:1)
因此,您希望创建一个动态增长的堆栈,并且您已经有一个答案可以解释您的代码出错的地方。设计似乎有点复杂,因此我会向您展示一些解决方案的注释代码,我只考虑直接,只使用一个struct
:
#include <stdio.h>
#include <stdlib.h>
typedef struct Stack
{
size_t capacity; // how many items the stack can hold right now
size_t index; // index of the first unused element
// (kind of a "stack pointer")
int stack[]; // the elements, variable length
} Stack;
Stack *Stack_create(size_t n)
{
// create stack with room for `n` elements
Stack *self = malloc(sizeof(Stack) + n * sizeof(int));
// you need to add `n * sizeof(int)` here for the flexible array member
if (!self) exit(1);
self->capacity = n;
self->index = 0;
return self;
}
void Stack_destroy(Stack *self)
{
if (!self) return;
free(self);
}
void Stack_push(Stack **self, int val)
{
Stack *s = *self;
if (s->index == s->capacity)
{
// if necessary, double the number of elements the stack can hold
s->capacity *= 2;
s = realloc(s, sizeof(Stack) + s->capacity * sizeof(int));
if (!s) exit(1);
*self = s;
}
s->stack[s->index++] = val;
}
int Stack_pop(Stack *self, int *val)
{
if (self->index)
{
*val = self->stack[--self->index];
return 1;
}
else
{
return 0;
}
}
int main(void)
{
Stack *stack = Stack_create(5);
Stack_push(&stack, 47);
Stack_push(&stack, 12);
Stack_push(&stack, 73);
Stack_push(&stack, 5);
Stack_push(&stack, 13);
Stack_push(&stack, 23);
int val;
while (Stack_pop(stack, &val))
{
printf("%d ", val);
}
putchar('\n');
Stack_destroy(stack);
return 0;
}
关于此的说明:
为了简洁起见,malloc()
和realloc()
上的错误检查很少。在实践中,当然没有什么可以做的,也许exit(1)
就足够了,但是如果你的程序更复杂,你可能想要向调用者返回一个错误,所以它可以例如fflush()
个文件等。
您通常希望避免realloc()
次呼叫的批次(它们可能很昂贵)。如果需要更多空间,则提前分配一些空间并将空间加倍是这种数据结构的常用方法。
如果您不想将双指针传递给Stack_push()
,您必须使用指针代替灵活数组成员,如下所示:
typedef struct Stack
{
size_t capacity;
size_t index;
int *stack;
} Stack;
然后,您必须通过单独调用malloc()
为此分配空间,并且只需要此成员上的realloc
。