代码之家  ›  专栏  ›  技术社区  ›  Captain Patches

动态数组大小调整混乱或损坏错误

  •  -1
  • Captain Patches  · 技术社区  · 6 年前

    目标是创建一个平衡符号检查器,程序查找这些符号的输入<{[(),然后检查它们是否关闭。每次遇到其中一个时,都会将其推送到堆栈上。一旦堆栈满了,就需要分配更多的内存。 我不确定这个错误是从哪里来的,但我相信可能是我的push函数造成的。我非常困惑,到处都在搜索(在这里查看每个标题相似的问题,并尝试建议的解决方案),试图解决它。据我所知,这个错误意味着我试图两次释放某些东西,但我不知道会在哪里发生。我尝试了多种不同的方法来做这件事,但似乎没有任何效果。请帮忙。

    对如何调整动态数组的大小也有点困惑。说到这里,我以为你做了一个新的temp*指向数组内容,用malloc调整了原来的大小,删除了所有内容,然后把保存在temp中的内容放回去。我已经看到它做了几个不同的方式,不确定哪种方式在哪种情况下使用。非常感谢。

    typedef struct{    //for reference
         char *darr;
         int size;
         int top;
     }
     stack;
    
    void push (stack *s, char tsymbol){
     if (s->top == s->size){   //if stack is full
        char *temp = (char*)malloc(sizeof(char)*s->size);
        temp = s->darr;
        free(s->darr);
        s->darr = temp;
        s->size += 2;    
       }   
    s->darr[++(s->top)] = tsymbol;
    //s->top = s->top + 1;
    }
    

    if (s->top == s->size-1){   //if stack is full
       char *pTemp;
       pTemp = (char*)malloc(sizeof(char)*((s->size)+2));
       int i;
       for (i=0; i<(s->top); i++){
           pTemp[i] = s->darr[i];
       }
       free (s->darr);
       s->darr = pTemp;
     }
       s->darr[s->top] = tsymbol;
       s->top = s->top + 1;
    }
    
    1 回复  |  直到 6 年前
        1
  •  0
  •   Barmar    6 年前

    您的代码存在以下问题:

    1. size 之后 使用当前大小进行分配。
    2. 您没有将旧数组的内容复制到新数组。
    3. 你分配 temp = s->darr; 你打电话之后 malloc() ,因此将丢失指向新内存的指针。
    4. 稍后再分配 s->darr = temp; free(s->darr) . 但是因为#3, temp s->darr ,所以这没什么用,现在 仍指向释放的内存。下次你打电话的时候 push()
    5. 分配给 s[++(s->top)] . 但由于在分配之前没有增加大小,因此会在数组外部进行分配。
    6. 您需要在 s->top == s->size-1 0 size-1 ;分配给 s->darr[s->size] 会写越界。为了安全起见,使用 >= 而不是 ==
    7. . 使用pre-increment,可以跳过数组的第一个元素,也可以在数组之外进行写操作,除非使用增长测试 s->size-2 .

    这是正确的版本。

    void push (stack *s, char tsymbol){
        if (s->top >= s->size - 1){   //if stack is full
            char *temp = alloc(s->size + 2);
            memcpy(temp, s->darr, s->size);
            s->darr = temp;
            s->size += 2;    
        }   
        s->darr[(s->top)++] = tsymbol;
    }
    

    Do I cast the result of malloc?