Ответы пользователя по тегу C++
  • Управление памятью в С++?

    Ckpyt
    @Ckpyt
    Тут надо понимать, что такое "мусор" в jave. Как правило, это объекты, на которых не осталось указателей. Или все указатели друг на друга замкнуты. Такой "мусор" вызывает рост использованной памяти, при том, что никто ей и не пользуется. Это называется "утечка памяти". Естественно, такое положение дел никого не устраивает, и время от времени запускается сборщик мусора, который и грохает все утечки.
    Теперь, переходим к С++. Тут все управление памятью ложиться на пользователя.
    Выделение памяти бывает двух видов: на стеке и в куче. На стеке - самое простое, но не самое безопасное, когда значение должно где-то храниться.
    Самый простой пример int x[10]; - выделяет 10*sizeof(int) байт на стеке.
    Сразу покажу чем это плохо: предположим, у вас есть два потока, и надо заполнить и передать задание второму потоку. Мы создаем внутри функции массив, заполняем его, передаем второму потоку и выходим из функции. Память при этом освободилась и уже какой-то другой поток в нее пишет.
    Второй поток при этом наконец-то добрался до задания и начинает работать с переданным массивом.
    В итоге, он сам получает бред, да еще и если пишет в массив выходные значения, то и портит память другому потоку. Тоже самое будет, если вы сохраните указатель на массив во внешнее поле и попробуете получить к нему доступ из другой функции.
    Так мы приходим к тому, что нам нужна независимая память. Или память на куче.
    int* x = new int[10];
    С такой памятью легче все работать как с передаваемым массивом. Эта память нигде не испортится и в общем и целом, с ней все будет хорошо. Есть только одна проблема: ее надо прибрать. Т.е. где-нибудь должен быть delete.
    Пока один поток и четкая и понятная структура приложения, все легко и просто. Когда у нас начинается многопоточность и самописные библиотеки, то все резко усложняется. И тут на помощь приходят умные указатели - shared_ptr, к примеру, делает следующее: увеличивает счетчик владений объектом на единицу каждый раз, когда указатель присваивается. И уменьшает на ту же единицу, когда вызывается деструктор. Если счетчик хранения равен нулю, то умный указатель корректно удаляет объект и утечки памяти не происходит.
    В общем и целом, советую почитать про умные указатели.
    Ответ написан
    Комментировать