C ++ памяти - PullRequest
       10

C ++ памяти

0 голосов
/ 09 февраля 2012

Я учил себя C ++, и кто-то сказал мне, что C ++ не имеет сборщика мусора. Теперь я не уверен, в какой степени это значит.

Допустим, у меня есть этот код:

double multiply (double a, double b) {
    double result = a * b;
    return result;
};
int main (char* args[]) {
    double num1 = 3;
    double num2 = 12;
    double result = multiply(num1, num2);
    return 0;
}

Метод умножения содержит внутреннюю переменную «результат». Теперь адрес памяти для переменной «result» все еще выделен и / или заблокирован? А как насчет параметров "а" и "б"?

Ответы [ 6 ]

5 голосов
/ 09 февраля 2012

Стандартный C ++ вообще не имеет сборщика мусора.

Но автоматические переменные (переменные "стека") очищаются, когда заканчивается их область действия, вызывая деструкторы, если / когда это необходимо. (Все переменные в вашем примере являются автоматическими.)

Вам нужно беспокоиться о динамическом распределении: все, что вы создаете с помощью оператора new. Они не очищаются автоматически - вам нужно delete, иначе они будут вытекать. (Или используйте умные указатели.)

2 голосов
/ 09 февраля 2012

Сборка мусора означает, что ваш мусор (не доступная / ссылочная память в куче 1002 *) будет освобожден автоматически.Локальная память / переменные (локальные переменные) не будут выделяться, но помещаются в стек и автоматически освобождаются, если вы покидаете блок, в котором вы определили переменную.

Так что если вы используете свой кодты в порядке.Но если вы используете

double multiply (double a, double b) {
    double *result = new double;
    *result = a * b;
    return *result;
};

, то память в result все еще выделяется, блокируется и теряется.См. Также http://en.wikipedia.org/wiki/Call_stack и http://en.wikipedia.org/wiki/Dynamic_memory_allocation#Dynamic_memory_allocation.

2 голосов
/ 09 февраля 2012

Все переменные, которые вы упомянули, находятся в стеке. Как только они выходят из области видимости, память освобождается автоматически.

1 голос
/ 09 февраля 2012

C ++ имеет два основных типа памяти, где размещаются объекты: стек и свободное хранилище (куча). Объекты в стеке выделяются и освобождаются вручную, и они включают в себя параметры функции, автоматические (локальные) переменные, временные объекты, возвращаемые значения. Объекты в бесплатном хранилище (куче) вместо этого управляются явно с new, new[], delete и delete[]. Вы также можете управлять необработанной памятью из бесплатного хранилища, используя malloc / free или используя причудливые именованные функции operator new и operator delete и их [] аналоги.

Для объектов, управляемых в бесплатном хранилище на C ++, программист обязан позаботиться о распределении и освобождении ... в других языках это вместо этого автоматическое. В C ++ также необходимо обратить внимание на то, что время жизни стековых объектов связано с областью действия (и, например, хранение или возврат адреса локальной переменной является распространенной ошибкой или множеством ошибок), хотя это также не проблема на других языках.

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

С другими языками компилятор анализирует код и решает, где можно использовать выделение стека, а где нет, вместо этого в C ++ это работа для программиста.

Обратите внимание, что в C ++ управление памятью на самом деле немного более замысловатое, чем это объяснение (например, есть также память, в которой хранятся объекты исключений, могут быть настраиваемые распределители для классов и параметр распределителя для контейнеров), но программисту редко нужно это учитывать.

1 голос
/ 09 февраля 2012

На самом деле, C ++ - это очень хорошее управление ресурсами! Он не выполняет сборку мусора для объекта, размещенного в куче. Вы, разумно, ничего не выделяли в куче, и во многих случаях, когда вы делаете это, вы, вероятно, не делаете это явно (например, при использовании std::vector<T>). Чтобы получить утечку ресурсов, с которой сталкивается сборщик мусора на других языках, объекты выделяются в куче с использованием new: вам нужно связать каждое выделение памяти (ну, в действительности, любое выделение ресурсов) с соответствующим выпуском. Использование таких вещей, как std::vector<T> и std::shared_ptr<T> имеет дело с огромным количеством утечек ресурсов в C ++.

То есть в вашем примере программы нет утечек ресурсов.

0 голосов
/ 09 февраля 2012

Это (в основном, игнорируя внешние библиотеки) верно, что C ++ не имеет сборщика мусора. Вместо этого у него есть концепция автоматического хранения.

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

В конце области действия multiply, result уничтожается, а память, в которой он хранится result, освобождается.

Это "автоматическое управление памятью" не использует сборщик мусора и является полностью детерминированным.

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