2013-03-20 3 views
2

Итак, я изучал ООП на C++, и я подумал, что было бы хорошей практикой написать собственный собственный класс строк (для учебных целей, конечно). У меня возникла проблема, которую я не знал, как ее решить. Ниже приведен код заказа:Избегайте утечки памяти

class String { 
    char *str; 
public: 
    String(char const *str); 
    ~String(); 
    String operator + (char const *str); 
}; 

String::String(char *str) { 
    this->str = _strdup(str); 
} 

String::~String() { 
    free(this->str); 
} 

String String::operator+(char const *str) { 
    char *temp = (char *) malloc(strlen(str) + strlen(this->str) + 1); 
    strcpy(temp, this->str); 
    strcat(temp, str); 
    return temp; 
} 

Проблема в том, что эта часть кода вызовет утечку памяти. Возврат из «operator +» вызывает мой конструктор, который копирует temp, выделяя больше памяти, и я не мог найти способ, как я могу его освободить.

+9

Вы должны быть следуя правилу трех /5. Кроме того, предпочитайте 'new []' и 'delete []' to 'malloc' и' free'. – chris

+1

Не говоря уже о полном параметре LULT NULL, который проверяет и возвращает значения, которые полностью отсутствуют. – WhozCraig

+0

Написание собственного строкового класса - хорошая вещь для учебных целей ... но написать хороший класс строк - непростая задача. –

ответ

7

Ваш operator + определяется как возвращающий String, но вы возвращаете char*, что означает, что компилятор неявно преобразовывает его с помощью конструктора. Это копирует строку, но не освобождает оригинал, который вы, следовательно, просачиваетесь.

Там много вещей, которые вы могли бы сделать, чтобы улучшить код, как и другие предложили, но исправить фактическую утечку вы могли бы сделать это:

String String::operator+(char const *str) { 
    char *temp = (char *) malloc(strlen(str) + strlen(this->str) + 1); 
    strcpy(temp, this->str); 
    strcat(temp, str); 
    String strTmp(temp); 
    free(temp); 
    return strTmp; 
} 
+0

+1 Я был в середине написания почти точно такого же ответа – Lorkenpeist

+0

Обратите внимание, что для будущих посетителей этот ответ предполагает, что вы написали оператор копирования и оператор присваивания копии. В противном случае вы просто заменяете утечку для двойного 'free()' и сбоя. – mythagel

1

Вы забыли реализовать operator = и конструктор копирования. Если вы не предоставите свой собственный, компилятор выполнит их для вас, сделав членную мудрую копию, которая приведет к утечке памяти.

+0

Я этого не делал, я просто не вводил код здесь. Если это необходимо - скажите мне, я добавлю. – Arnas

+1

@ Арнас, Ну, лучше, чем жаль. Вы не поверили бы количеству повторяющихся вопросов здесь, где это проблема. – chris

3

Дать класс строк не является простой задачей, если вы хотите сделать это правильно. Для конкретной проблемы, с которой вы сталкиваетесь, я могу сделать пару рекомендаций ...

Реализовать append() или operator+=, который создает буфер большего размера, копирует содержимое, свопирует внутренний буфер и вновь созданный и выпускает старый.

Тогда operator+ становится тривиальной задачей:

String operator+(String lhs, String const & rhs) { 
    lhs += rhs;     // lhs.append(rhs); 
    return lhs; 
} 

(Конечно, это предполагает, что вы предоставите правильные определения конструктора копирования и оператора присваивания)

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