Параметр метода C ++, переданный по ссылке - вопрос памяти - PullRequest
2 голосов
/ 26 марта 2010

Предположим,

void proc(CString& str)
{
  str = "123";
}

void runningMethod()
{
  CString str="ABC";
  proc(str);
}

Я так понимаю, что при выходе из Метода str будет освобожден автоматически; в этом случае, как C ++ удаляет старые данные («ABC»)?

Спасибо,

Gil.

Ответы [ 5 ]

5 голосов
/ 26 марта 2010

"ABC" было перезаписано, когда вы сказали = "123".

Внутренне строка - это массив символов. При запуске он создал новый буфер, содержащий {'A', 'B', 'C', '\0'}. Когда вы назначаете, он просто пишет '1' над 'A' и т. Д.

Когда он был уничтожен, он удалял буфер.

1 голос
/ 26 марта 2010

То же самое происходит, как если бы вы написали:

CString foo = "ABC";
foo = "123";
0 голосов
/ 26 марта 2010

Несколько вещей, о которых следует помнить здесь. Во-первых, оператор = класса, как правило, позаботится об удалении всего, на что он ссылался, до назначения новых данных. Что ж, это не совсем так, часто умный разработчик реализует operator =, сначала создав копию входящего класса, а затем поменяв текущие данные с новым временным, который теперь владеет, и удаляет его. Однако важно помнить, что до появления функции operator = старые данные, вообще говоря, отбрасываются.

Еще одна вещь, которую нужно иметь в виду, это то, что "ABC" является строковым литералом. Стандарт на самом деле не определяет, как они должны храниться, он просто устанавливает ограничения, которые допускают определенные обычные реализации. Очень часто этот строковый литерал будет отображаться как элемент только для чтения в данных программы. В этом случае он никогда не будет удален, пока изображение программы загружено в память (когда оно работает в основном). Вот и вся причина, почему такой код - UB:

<code>
void f()
{
  char * x = "hello"; // points to a string literal.
  x[0] = 'H';
}</p>

<p>// correct implementation is:
void f()
{
  char x[] = "hello"; // reserved an array of 6 characters and copies string literal content.
  x[0] = 'H';
}
0 голосов
/ 26 марта 2010

В большинстве случаев при выполнении задания в proc() «Азбука» будет освобождена. Обычно это делается в методе перегруженного оператора. Например здесь у вас есть пример того, как выглядит такая перегрузка.

String& String::operator= (const String& other)
{
        char* otherdata = other.data;
        char* olddata = data;
        if (otherdata != 0)
        {
                data = new char[other.length+1];
                length = other.length;
                memcpy(data,otherdata,other.length+1);
        }
        else
        {
                data = 0;
                length = 0;
        }
        if (olddata != 0)
        {
                delete[] olddata;
        }
    return *this;
}
0 голосов
/ 26 марта 2010

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

...