Я отлаживал его в течение 4 часов, но все еще не могу найти ошибку - PullRequest
1 голос
/ 17 декабря 2011

Эта программа вводит некоторую строку из файла, затем помещает строки в LineBuf одну за другой, после того как мы вставим одну строку в LineBuf , напечатаем LineBuf , затем сделайте LineBuf пустым.

Это мой код:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *LineBuf = NULL;
int BufLen = 0;

void PushToBuf(char c)
{
    LineBuf = (char *)realloc(LineBuf, (BufLen+2)*sizeof(char));
    LineBuf[BufLen] = c;
    BufLen++;
    LineBuf[BufLen] = '\0';
}

int main()
{
    char temp[20];
    int i;
    FILE *fp;
    fp = fopen("input", "r");

    while (fgets(temp, 20, fp) > 0)
    {
        /*Push temp into buf*/
        for (i = 0; i < strlen(temp); i++)
            PushToBuf(temp[i]);

        /*print buf*/
        printf("%s\n", LineBuf);
        printf("%d\n", BufLen);

        /*make buf empty*/
        free(LineBuf);
        BufLen = 0;
    }
    return 0;
}

Это мой входной поток:

This is a test. Good evening
bye~

Это результат выполнения:

This is a test file
19
. Good evening

15
 glibc detected  ./a.out: double free or corruption (fasttop): 0x00000000023fa250 

======= Backtrace: =========

/lib/libc.so.6(+0x775b6)[0x7f2ad01bf5b6]
/lib/libc.so.6(cfree+0x73)[0x7f2ad01c5e83]
./a.out[0x400868]
/lib/libc.so.6(__libc_start_main+0xfd)[0x7f2ad0166c4d]
./a.out[0x400699]

Ответы [ 4 ]

1 голос
/ 17 декабря 2011

Вы пытаетесь realloc free 'указатель; Вы не можете сделать это!

1 голос
/ 17 декабря 2011

Как работает realloc ( void * ptr, size_t size ):

Размер блока памяти, на который указывает параметр ptr, равен изменено на size байт, увеличивая или уменьшая объем памяти доступно в блоке. Функция может переместить блок памяти в новое место, в котором если возвращено новое местоположение.

В случае, если ptr равно NULL, функция ведет себя точно так же, как malloc, присваивая новый блок size байтов и возвращая указатель на начало этого.

В вашем случае указатель уже освобожден, но все еще не NULL, поэтому, когда программа пытается переместить этот блок памяти, это вызывает повреждение памяти.

Чтобы решить эту проблему, вы должны выполнить одно из следующих действий:

  • Удалить free().
  • Используйте malloc вместо realloc.
  • Установите LineBuf в NULL после free().
1 голос
/ 17 декабря 2011

Это не делает LineBuf пустым. Это освобождает место для хранения LineBuf. Когда вы позже перераспределяете LineBuff, он пытается перераспределить освободившееся пространство.

    /*make buf empty*/
    free(LineBuf);

чтобы решить проблему, выведите свободную из цикла while. и пустой свободный байт, устанавливающий все данные, которые он хранит, в ноль.

для (int i = 0; i

0 голосов
/ 17 декабря 2011

free (LineBuf) освобождает память, но вы снова используете LineBuf позже при вызове realloc. Вы должны установить LineBuf в NULL после его освобождения, тогда realloc будет выполнять malloc, а не перераспределять. Имейте в виду, что всегда полезно устанавливать указатели в NULL после их освобождения. Это помогает определить, используете ли вы указатели для освобождения памяти.

Кстати, глядя на твой код, я не совсем уверен, что ты собираешься делать. В зависимости от того, что вы хотите сделать, вы можете избавиться от LineBuf или от fgets. Также: вызов strlen для каждого i не очень производительный, лучше проверить temp [i]! = '\ 0'.

...