2012-04-28 4 views
3

Я новичок с valgrind, поэтому я могу сделать что-то не так, но что мне делать, если valgrind сообщает больше frees, чем allocs?valgrind сообщает больше frees, чем allocs

Получил SSCCE здесь:

#include <cstring> 

class something 
{ 
protected: 
    char* ptr; 
public: 
    something() {ptr = NULL;} 
    something(const char* value) { 
     ptr = new char[strlen(value)+1]; strcpy(ptr, value); 
    } 
    ~something() {delete[] ptr; ptr = NULL;} 
}; 

int main() 
{ 
    something x; 
    x = "123"; 
    return 0; 
} 

, который отлично компилируется и работает тоже хорошо, но Valgrind говорит

==15925== Invalid free()/delete/delete[] 
==15925== at 0x40221EA: operator delete[](void*) (vg_replace_malloc.c:364) 
==15925== by 0x8048689: something::~something() (test.cpp:12) 
==15925== by 0x80485F5: main (test.cpp:19) 
==15925== Address 0x42b7028 is 0 bytes inside a block of size 4 free'd 
==15925== at 0x40221EA: operator delete[](void*) (vg_replace_malloc.c:364) 
==15925== by 0x8048689: something::~something() (test.cpp:12) 
==15925== by 0x80485E5: main (test.cpp:18) 
==15925== 
==15925== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 18 from 1) 
==15925== malloc/free: in use at exit: 0 bytes in 0 blocks. 
==15925== malloc/free: 1 allocs, 2 frees, 4 bytes allocated. 
==15925== For counts of detected errors, rerun with: -v 
==15925== All heap blocks were freed -- no leaks are possible. 

, и я не уверен, почему.
Конечно, я могу сделать обоснованные догадки - очевидно, оскорбительная линия - это то, где говорится x = "123";, и если вы прокомментируете это, все будет хорошо. Но почему же тогда компилятор считает, что все в порядке, даже с -Wall -Wextra -pedantic? Забыл ли я о компиляторе, который может сказать, что у этой программы есть проблемы?

ответ

1

Вы забыли осуществить Rule of three.
Вам следует предоставить конструктор копирования, а также оператор присваивания копии.

x = "123"; 

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

+0

Определенно. Но тогда остается мой последний вопрос: существуют ли компиляторы для 'g ++', которые могут обнаружить такие вещи? –

+0

@MrLister: К сожалению, ни одно правило из трех правил не является частью стандарта C++ (оно должно идеально быть в идеале), поэтому компиляторы не жалуются на то, что это нарушено. Также AFAIK не существует расширения компилятора, которое сообщает об этом. –

1

x = "123" равнозначно x = something("123"), который вызывает неявный оператор присваивания копий. Временный something разрушен, но тогда так x, оба из которых delete [] тот же необработанный указатель.

Решение должно следовать за Rule of Three или использовать интеллектуальные указатели/контейнеры для управления памятью для вас.

0

Класс something содержит необработанный указатель, который неправильно управляется его конструктором копирования и присваиванием. Не используйте необработанные указатели, или, если необходимо, более тщательно определите методы класса. Но на самом деле не используйте необработанные указатели.

+0

Вы не должны бояться сырьевых указателей. Пока вы убедитесь, что ваш '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' '' В моем примере только constuctor может выполнять 'new', и только деструктор может сделать' delete'. –

+0

Эй, ты тот, кто пришел сюда, потому что у тебя была проблема, которая никогда не случилась бы, если бы ты использовал умные указатели. Практически нет оснований использовать исходные указатели сегодня, когда вы управляете временем жизни объекта, что с разнообразием, доступным в разных библиотеках, а недавно даже в стандартном C++. То, что вы сейчас говорите * Я * не должен бояться использования исходных указателей, когда вы сами не смогли правильно их использовать, я не знаю. –

+0

О, извините, если я обиделся. Может быть, это просто реакция от моего имени на принудительное воздействие на C#, где язык держит вас за руку и не позволяет делать то, что, по вашему мнению, может причинить вам боль. Принимая во внимание, что я больше узнаю от таких ошибок. Опять же, извините. –

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