2013-05-29 4 views
0

Я получаю утечку памяти из следующих функций:памяти через новый [] никогда не вызывая новый

int ReadWrite(int socket, char *readfile) { 
    FILE *rf = NULL; 
    rf = fopen(readfile, "rb"); 
    fseek(rf, 0, SEEK_END); 
    int len = ftell(rf); 
    rewind(rf); 

    char readbuf[len + 1]; 

    int res = fread(readbuf, len, 1, rf); 
    readbuf[len + 1] = '\0'; 
    fclose(rf); 
    while (1) { 
    int wres = write(socket, readbuf, res); 
    if (wres == 0) { 
     cerr << "socket closed prematurely" << endl; 
     close(socket); 
     return EXIT_FAILURE; 
    } 
    if (res == -1) { 
     if (errno == EINTR) 
     continue; 
     cerr << "socket write failure: " << strerror(errno) << endl; 
     close(socket); 
     return EXIT_FAILURE; 
    } 
    break; 
    } 
    return EXIT_SUCCESS; 
} 

Valgrind говорит мне, что я просачиваться число байтов, которые находятся в ReadFile (фактический файл, не имя ReadFile) через эту операцию:

Address 0x4c3b67e is 0 bytes after a block of size 14 alloc'd 
at 0x4A07C84: operator new[](unsigned long) (vg_replace_malloc.c:363) 

Что меня смущает то, я никогда не использовать новый [] в моем коде. Я проверил fopen, ftell и fread, чтобы посмотреть, есть ли у них скрытые «gotcha's», где они называются new [], но ничего не нашли в документации на cplusplus.com. Я пробовал все разные комбинации новых char []/delete [], malloc/free и переменных, связанных с стеками (выше), но каждый раз получаю одно и то же сообщение valgrind. Есть идеи? Благодарю.

+3

'char readbuf [len + 1];' недействителен C++. –

+1

Это очень странный код: 'char readbuf [len + 1]'. Какой компилятор вы используете? –

+4

Возможно, вы должны изменить 'readbuf [len + 1] = '\ 0';' to 'readbuf [len] = '\ 0';', если вы не намеренно пытаетесь перехватить readbuf. Кроме того, вы действительно используете C99, а не C++? –

ответ

0

Я выяснил, что проблема связана с файлом Makefile, который я использовал. Спасибо за понимание моего скольжения с char [], хотя!

+0

Можете ли вы объяснить, в чем проблема с Makefile? Благодарю. –

+0

К сожалению, я не помню особую причину, по которой Makefile вызывает проблемы. Но я помню, потому что у меня было недоразумение о том, как работают Make-файлы. Извините, у меня нет больше для вас - лучшее, что я могу сделать, это указать вам на учебник по Makefiles (http://www.cs.umd.edu/class/fall2002/cmsc214/Tutorial/makefile.html). Надеюсь, это поможет. –

7

вы звоните

  • char readbuf[len + 1];

    а затем

  • readbuf[len + 1] = '\0';

не будет, что переполнение массива?

+0

Не говоря уже о том, что 'char readbuf [len + 1]' недействителен C++, поскольку 'len' не' const'. –

+0

@NikBougalis: Это нестандартно, но (A) GCC разрешил его некоторое время, и (B) они работают над его стандартизацией. –

+1

@MooingDuck gcc может поддержать это, и в этом случае руководство gcc должно объяснить, как следует освободить память (обновление: оно автоматически освобождается компилятором в [docs] (http://gcc.gnu.org/onlinedocs /gcc/Variable-Length.html)), но сегодня он не является стандартным, поэтому код недействителен C++.Это действительный «gcc-extended C++», но это не то же самое, что «C++». –

0

Ну, вы объявляете свой массив readbuf с непостоянным размером (т. Е. С размером времени выполнения). Это формально запрещено в C++. Такая функция существует в C99, но не в C++. Ваш код даже не компилируется в педантическом компиляторе C++. И ваш вопрос помечен [C++].

Но вполне возможно, что ваш компилятор реализует эту функцию как нестандартное расширение и создает такие массивы через неявный вызов new[]. Вот почему вы получаете сообщение об ошибке, которое ссылается на new[], даже если вы не используете new[] явно.

Конечно, ответственность компилятора заключается в том, чтобы освободить такие массивы, когда они заканчивают свою жизнь. Я подозреваю, что компилятор делает все, что он должен делать, но valgrind путают что-то в действиях компилятора, что делает вывод о том, что это утечка памяти.

Кроме того, как уже отмечалось в других публикациях, вы производите доступ к вашему массиву из-за пределов доступа, что также может привести к возникновению абсолютно любых проблем во время выполнения, включая странный отчет от valgrind.

Смежные вопросы