Динамическое изменение размеров массива, путаница, двойное освобождение или ошибка повреждения - PullRequest
0 голосов
/ 15 февраля 2019

Цель состоит в том, чтобы создать сбалансированную проверку символов, программа ищет ввод этих символов <{[(, а затем проверяет, закрыты ли они. Каждый раз, когда встречается один из них, он должен быть помещен в стек.Как только стек заполнен, необходимо выделить больше памяти. Я не уверен, откуда эта ошибка, но я полагаю, что это может быть из-за моей функции push. Я очень запутался и искал везде (просмотрел каждый вопрос спохожий заголовок здесь и попытался предложить решения), чтобы попытаться исправить это. Из того, что я мог собрать, эта ошибка означает, что я пытаюсь освободить что-то дважды, но я не могу понять, где это будет происходить. Я пробовал несколько разных способовделать это, и, кажется, ничего не работает. Пожалуйста, помогите. </p>

Также немного запутался в том, как изменить размер динамического массива. Переходя к этому, я думал, что вы сделали новый темп *, указывающий на содержимое массива, изменил размер оригинала с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 голосов
/ 15 февраля 2019

У вас есть следующие проблемы с вашим кодом:

  1. Вы увеличиваете size после Вы выделяете, используя текущий размер.
  2. Вы 'не копировать содержимое старого массива в новый массив.
  3. Вы присваиваете temp = s->darr; после вызова malloc(), поэтому вы теряете указатель на новую память.
  4. Позже выназначьте s->darr = temp; после вас free(s->darr).Но из-за # 3 temp совпадает с s->darr, так что это ничего не делает, и теперь s->darr все еще указывает на освобожденную память.В следующий раз, когда вы позвоните push(), вы снова освободите его, что приведет к ошибке двойного освобождения.
  5. Вы присваиваете s[++(s->top)].Но так как вы не увеличивали размер перед выделением, это назначает вне массива.
  6. Вам нужно увеличить массив, когда s->top == s->size-1.Это потому, что индексы массива идут от 0 до size-1;присвоение s->darr[s->size] запишет за пределы.А для большей безопасности используйте >= вместо ==.
  7. . Вы должны использовать постинкремент при сохранении нового элемента в s->darr.С предварительным приращением вы пропускаете первый элемент массива, а также можете писать за пределы массива, если только не использовался тест роста 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;
}

Также см. Использовать ли я результат malloc?

...