управление памятью - PullRequest
       1

управление памятью

2 голосов
/ 30 июля 2010

Это вопрос управления памятью о коде c ++.

using namespace std;
#include <iostream>
#include <string.h>

int main()
{
 string a="first";
 string *b= new string;
 *b=a;
 a="second";
 cout << *b << ", " << a;
 delete b;
 return 0;
}

Мы можем освободить блоки памяти, в которых хранится строка, на которую указывает b.Я предполагаю, что это означает, что b больше не имеет никакого смысла, как только это будет сделано.Мы можем освободить b, чтобы освободить память.Почему мы не можем освободить?Я знаю, что мы можем только удалить / освободить указатели, но строка a должна где-то занимать память.Есть ли способ освободить память, которую занимает строка a?Если имеется достаточное количество строк, инициализированных таким же образом, как инициализируется a, разве не возможно, что память заканчивается?

Ответы [ 6 ]

4 голосов
/ 30 июля 2010

Строка a объявлена ​​в стеке.Вы не можете вручную освободить его, но он будет автоматически освобожден, как только выйдет из области видимости (например, когда возвращается функция включения).Если вам нужно освободить эту функцию памяти, то объявите ее динамически (как вы это делали для b).

3 голосов
/ 30 июля 2010

Это довольно неловко.

<string.h> - заголовок C. Это не определяет string. Похоже, ваша версия <iostream> прямо или косвенно включает <string>, иначе будет ошибка.

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

В C ++ почти нет причин указывать на std::string. std::string не занимает много места без своего содержимого и управляет памятью для самого содержимого. Вы путаете это с char *?

Вы new a std::string для b, а затем вы присваиваете другой адрес b без delete памяти. Это утечка памяти. То, что вы new отредактировали для b, по-прежнему выделено, но нет способа delete сделать это, поэтому оно будет занимать память на время работы программы.

Затем, как только вы присвоили адрес от a до b, вы delete b;. Это плохая идея, и она, вероятно, испортит что-то важное, возможно, непредсказуемым образом. Только delete памяти, которую вы приобрели с new. (Здесь важно для delete ing не то, что b является указателем и должен быть удален, а то, что память, на которую он указывает, не была получена через new.)

Управление памятью работает примерно так. Строковый литерал размещается где-то. Все, что вы знаете, это то, что вы не должны пытаться изменить его или delete каким-либо образом. Используйте значение и не трогайте остальное. A std::string управляет памятью для своего собственного содержимого и позаботится об этом в своем деструкторе. Переменная, объявленная в функции или другом блоке, будет уничтожена, как только она выйдет из области видимости (хотя все, на что она может указывать, не будет уничтожено автоматически; только если это умный указатель или она управляет собственной памятью или чем-то еще). Если у вас new памяти, не выбрасывайте значение указателя, пока оно не станет delete d. Если у вас нет new памяти, не delete это.

3 голосов
/ 30 июля 2010

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

Вызов clear() или назначение из пустой строки может не освободить хранилище. Чтобы убедиться, что он освобожден, нужно поменять строку с недавно созданным временным; деструктор временного освободит его.

string().swap(a); // replaces `a` with an empty string

Вы также можете сделать это с любым из стандартных контейнеров.

2 голосов
/ 30 июля 2010

Автоматические объекты (такие как ваш a) уничтожаются, когда они выходят за рамки.Смотрите пример ниже:

int main()
  {

    {
    string a="first";
    string *b= new string;
    *b=a;
    a="second";
    cout << *b << ", " << a;
    delete b; //b gets freed
    } //a gets freed because it has gone out of scope   
 /* You can write more code here that does not need a */
 return 0;

}

0 голосов
/ 30 июля 2010

a здесь автоматически распределяется по «стеку» и будет автоматически уничтожаться / освобождаться при выходе из области видимости.

Когда вы используете динамическую память с new / malloc, она распределяется по «куче», которая является просто частью памяти, доступной для программы. Вы должны управлять этим вручную, и программа не знает, когда от этого избавиться.

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

Edit: это дает более полное объяснение, чем то, что я пытаюсь сказать: http://en.wikipedia.org/wiki/Malloc#Rationale

0 голосов
/ 30 июля 2010

Память, выделенная для a , будет автоматически освобождена после возврата из функции.

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