动态数组大小调整混乱双重释放或损坏错误

时间:2019-02-15 02:21:42

标签: c arrays dynamic malloc free

目标是创建一个平衡的符号检查器,程序查找这些符号<{[(的输入,然后检查它们是否闭合。每次遇到其中一个,将其压入堆栈。一旦堆栈已满,就需要分配更多的内存。 我不确定此错误来自何处,但我相信可能是由于我的推送功能引起的。我非常困惑,已经到处搜索(在此处查找具有类似标题的每个问题,并尝试了建议的解决方案)以尝试修复它。从我所能收集到的信息来看,该错误意味着我试图释放两次,但是我不知道会在哪里发生。我尝试了多种不同的方法来执行此操作,但似乎没有任何效果。请帮忙。

对于如何调整动态数组的大小也有些困惑。进入这个过程,我以为您做了一个指向数组内容的新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 个答案:

答案 0 :(得分:0)

您的代码存在以下问题:

  1. 在使用当前大小分配之后,您正在增加size
  2. 您不会将旧数组的内容复制到新数组。
  3. 在调用temp = s->darr;之后分配malloc(),这样就丢失了指向新内存的指针。
  4. 稍后在s->darr = temp;之后分配free(s->darr)。但是由于#3,temps->darr相同,所以它什么也没做,现在s->darr仍指向释放的内存。下次调用push()时,将再次释放它,这将导致双重释放错误。
  5. 您分配给s[++(s->top)]。但是由于您在分配之前没有增加大小,因此会在数组外部分配。
  6. 您需要在s->top == s->size-1时增加数组。这是因为数组索引从0size-1;分配给s->darr[s->size]将超出范围。为了获得一点额外的安全性,请使用>=而不是==
  7. 将新项目存储到s->darr中时,应使用后增量。使用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?