动态地将内存分配给我的堆栈(仅在需要时)

时间:2015-05-10 19:10:31

标签: c

我需要为我的struct中的数组分配内存,当我定义struct时,这个数组在开头没有定义的大小:

typedef struct stacks {
    int size; // Stores the size of my -values- array
    int sp; //points to the top of the stack, my stackpointer
    int *values;
} STACKS;

所以,为了初始化我的结构我编写了这个函数,它为我的数组分配(使用calloc?)内存,并且我把SIZE变量放入我的数组的新大小。

#define MAXIMUM 10

int initStacks(STACKS *s){
    s->values = calloc(MAXIMUM,sizeof(int));
    s->size = MAXIMUM;
    s->sp = 0;
    return 0;
}

现在,如果我想将某些东西推到堆栈顶部(LIFO),我会使用它:

int pushs(STACKS *s, int x){
    if (s->sp==s->size) {
        realloc(s->values, MAXIMUM * sizeof(int));
        s->size*=2;
    }

    s->values[s->sp]=x;
    s->sp++;
}

这是正确的做法吗?

realloc在我的函数中应该正常工作吗?

非常感谢你的帮助!

编辑:

这会更有意义吗?这样,我真的不需要声明数组的值,用#define定义的最大值为10

typedef struct stacks {
    int size; // guarda o tamanho do array valores
    int sp;
    int *values;
} STACKS;


int initStacks(STACKS *s){
    s->values = calloc(1,sizeof(int));
    s->size = 1;
    s->sp = 0;
    return 0;
}

int isEmptys(STACKS *s){
    return((s->sp)==0);
}

int pushs(STACKS *s, int x){
    s->size++;
    realloc(s->values, s->size * sizeof(int));
    s->values[s->sp]=x;
    s->sp++;
}

2 个答案:

答案 0 :(得分:3)

假设您有一个原始大小因素(名称​​ capacity 将是合适的,如果不是这样),原始代码缺少几个:

  • 将大小与常量进行比较,而不是将当前sp与堆栈当前大小进行比较。
  • 保存测试 realloc
  • 的返回结果
  • 实际上并没有使分配加倍(你在realloc表达式中错过了2x。
  • 声明int返回结果,但不存在此类返回。
  • 无法将推送结果(成功与否)与呼叫者通信。对于这个缺失的返回结果,btw。

解决所有

int pushs(STACKS *s, int x)
{
    if (s->sp == s->size) 
    {
        void *pv = realloc(s->values, 2 * s->size * sizeof *(s->values));
        if (pv != NULL)
        {
            s->values = pv;
            s->size *= 2;
        }
        else
        {
            fprintf(stderr, "Failed to resize stack\n");
            return -1;
        }
    }

    s->values[s->sp++] = x;
    return 0;
}

未经测试,但希望足够接近。

祝你好运

答案 1 :(得分:-1)

虽然不能直接回答实际问题,但更多的是一般问题,我发布这个不适合评论。

如果您期望过度的推/弹操作和内存使用,可能会有以下选择:

typedef struct SubStack_s {
    struct SubStack_s *prev;
    int data[ENTRIES_PER_SEGMENT];
} SubStack;

typedef struct {
    SubStack *tos;    // init to NULL
    size_t sp;        // init to 0
} Stack;

基本思想是将元素推到每个子堆上直到满(如您所做)。如果当前的已满,则分配一个新的,链接它们(new->prev = old)并继续新的(将new存储到Stack.tos

一旦不再使用,Pop就会像每个亚组一样自由工作。

这个概念被称为"碎片堆栈"。它比realloc方法(它避免复制)更有效,并且不会碎片RAM,因为所有块都具有相同的大小。哦,它允许指向堆栈的指针,realloc-varaint没有,因为堆栈的地址可以改变。