C ++ странное поведение с переменными стека и функциями - PullRequest
0 голосов
/ 26 июня 2018

У меня есть String класс с char* buffer и unsigned int length.

Класс string имеет два конструктора:

String(const char* str);
String(const String& other);

и деструктор

 ~String()

, который удаляет массив символов с delete[] buffer;.

Оба конструктора создают новый буферный массив buffer = new char[size]; и заполняют его правильными данными из const char* string или const String& other. Строковый буфер завершается нулем.

В моей основной функции у меня есть следующий код:

int main() {
    String a("Hello");
    a = a.Replace('l', 'p');
    printf("%s\n", a.char_ptr());
}

Я ожидаю, что он выведет Heppo на консоль. Функция replace принимает два символа, где все вхождения первого заменяются вторым. Возвращает совершенно новый String:

String String::Replace(const char& a, const char& b) {
    const char* buf = ...;
    // Do the replacement and store the result in buf

    String s(buf);
    delete[] buf;
    return s;
}

Насколько я понимаю, компилятор вернет копию локальной переменной s. Из-за этого переменная a в main() должна быть совершенно допустимой String. Но вывод на консоль выглядит как ¦¦¦¦¦¦¦¦¦¦, который выглядит как неинициализированная память.

Еще страннее, когда я меняю свой основной метод на:

int main() {
    String a("Hello");
    String b = a.Replace('l', 'p');
    printf("%s\n", b.char_ptr());
}

Я вижу ожидаемый результат. После долгих чтений я не мог найти решение, так как эту проблему действительно трудно описать в поиске google / stackoverflow.

1 Ответ

0 голосов
/ 26 июня 2018

основная проблема - нарушение правила больших 3. Поскольку у вас нет тривиального деструктора, вы также должны определить конструктор копирования и оператор присваивания. Вы можете рассмотреть идиому копирования-обмена при реализации вышеуказанных функций. Если не определить ни одно из двух значений в присутствии нетривиального деструктора, это приведет к утечке ресурса (памяти в этом примере).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...