1

我编写了一个相当简单(ish)的堆栈实现,如果需要,它会自动增长其内部数组缓冲区。

为此,我自然会使用realloc - 它可以工作,但是,所有数组元素在 realloc() 调用之后都是反向排序的。

有问题的代码:

此示例将触发所述行为:

#include "pd/strlib.h"
#include "pd/stack.h"
#include "pd/memory.h"
#include <stdlib.h>
#include <stdio.h>

int main()
{
    int index = 0;
    char* buffer;
    pd_stack_t* stc = pd_stack_new();
    pd_stack_push(stc, "blue");
    pd_stack_push(stc, "green");
    pd_stack_push(stc, "red");
    pd_stack_push(stc, "yellow");
    pd_stack_push(stc, "pink");
    pd_stack_push(stc, "olive");
    pd_stack_push(stc, "beige");
    pd_stack_push(stc, "gold");
    pd_stack_push(stc, "grey");
    pd_stack_push(stc, "lime");
    pd_stack_push(stc, "khaki");
    while((index++) != 500)
    {
        pd_stack_push(stc, "__random_value__");
    }
    buffer = (char*)malloc(pd_stack_size(stc));
    pd_stack_dump_tomem(stc, buffer, 1);
    fprintf(stdout, "%s", buffer);
    return 0;
}

我真的对此一无所知。请帮忙!

4

2 回答 2

3

看起来 pd_stack_dump_tomem 从索引开始stack size并递减到 0,以相反的顺序附加元素。

将其更改为从 0 开始并迭代到stack size

(好像realloc没有关系)

于 2010-08-17T14:14:59.457 回答
1

您对堆栈代码有一些基本问题,所以我认为这realloc()不是您的问题。以下是您应该研究和解决的一些问题:

  • 堆栈上的顶部项目(当它不为空时)由 指向(gct->stackcount - 1),因为pd_stack_push()您将一个新项目存储在gct->ptr_stack[gct->stackcount]then incrementstackcount中。但是,当您访问顶部项目时,您使用了不正确的偏移量,gct->ptr_stack[gct->stackcount]而不是gct->ptr_stack[gct->stackcount - 1]. 特别是,在 中pd_stack_pop(),您释放了可能会破坏堆的项目,因为该堆栈位置中没有有效的指针。

  • 每次将新项目推入堆栈时,pd_stack_push()您都会调用。realloc()这不一定会损坏任何东西或导致缺陷,但它是不必要的 - 特别是因为您总是要求相同的大小分配。换句话说,realloc()除了第一个,你的电话应该是 nops。

  • pd_stack_pop_index()pd_stack_pop()除非您只弹出顶部项目(在这种情况下应该使用),否则甚至没有意义。你释放了可能在堆栈中间的东西,然后递减stackcount,基本上使顶部项目(不一定是你释放的)不可访问。堆栈中间已释放的项目现在将在弹出时再次访问/释放(假设pd_stack_pop()已修复)。

于 2010-08-17T15:08:54.627 回答