C Ошибка памяти в цикле -> неверное чтение размера 1 - PullRequest
0 голосов
/ 04 января 2019

У меня проблема с free() указателя malloc 'ed char в цикле.

В char *x=malloc(30) Я сохраняю строку, которую помещаю в стек с помощью add(x,queue). Проблема заключается в том, что я malloc выполняю это на каждой итерации, поэтому мне нужно free на каждой итерации, в противном случае у меня возникает утечка памяти в valgrind. Но если я поставлю free(x); в конце цикла while, у valgrind возникнет проблема с strcmp:

Invalid read of size 1
at 0x403045D: strcmp

by 0x048871: main(main.c 149) = else if(!strcmp(x,l))
address is 0 bytes inside block of size 30 free d

by 0x80488b8: main(main.c 164) = free(x);
block was allocked at
at 0x402c17c:malloc by main(main.c 129) =char *x=malloc(30);

Это странно, потому что мне не нужно это char *x до следующего распределения. Есть ли способ выделить его по-другому?

while ((a = getchar()) != EOF) {
    if (a == '<'){
        act = 1;
    }
    if (act == 1) {
        char *x=malloc(30);
        scanf("%29[^>]s",x);

        if(*x=='/'){

            void *l;
            l=pop_from_queue(queue);

            if(l==NULL)
                valid=1;
            else if(!strcmp(x+1,l))
                valid=0;
            else
                valid=1;

            act=0;
        }else{
            push_to_queue(queue,x); //push to stack
            count++;
            act=0;

        }
        free(x);       
     }
}

стек инициализации:

typedef struct {
  void **data;
  int head;
  int size;
  int count;

} queue_t;

queue_t* create_queue(int capacity){
  queue_t *queue=calloc(sizeof(queue_t),sizeof(queue_t));
  queue->head=0;
  queue->data=calloc(capacity+10,sizeof(void*));
  queue->count=0;
  queue->size=capacity+1;
  return queue;
}

функция pop:

void* pop_from_queue(queue_t *queue){

  if(queue->count==0)
    return NULL;
  else
    queue->count--;

  if(queue->head<0)
    return NULL;

  if(queue->head!=0)
    queue->head--;

  return queue->data[queue->head];

}

функция нажатия:

bool push_to_queue(queue_t *queue, void *data){
  if(queue->count==queue->size){
    queue->size+=10;
    queue->data=realloc(queue->data,queue->size*sizeof(void*));
  }
  queue->data[queue->head++]=data;
  queue->count++;

  return true;
}

Ответы [ 2 ]

0 голосов
/ 04 января 2019

Вы не должны делать free(x); после того, как push_to_queue(queue,x);, вы должны free(x); только тогда, когда if(*x=='/')

Поскольку вы высвободили переданное значение, при его извлечении вы получаете уже свободную память, которая используется strcmp

Так просто, я не видел этого раньше!

Примечание: вам нужно освободить значение, которое вы получаете через pop, если не NULL, независимо от результата strcmp

0 голосов
/ 04 января 2019

Вы не проверяете, что scanf() действительно обработал какие-либо данные перед разыменованием x.

Если scanf() не считывает данные и не сохраняет их в x, любое чтение из x будет недействительным.

...