Динамическое размещение и большие структуры данных в C ++ - PullRequest
1 голос
/ 16 октября 2019

В последнее время я узнал, что среди программистов C ++ существует консенсус, что операторов new, delete и delete[] следует избегать как можно чаще, как уже обсуждалось здесь , здесь или здесь . При поиске я даже наткнулся на апрельскую шутку о том, что эти операторы устаревают в C ++ 20.

Я пишу и поддерживаю программу на C / C ++, написаннуюна таком языке, чтобы продолжать использовать полезные библиотеки и классы, написанные другими программистами. Поскольку он должен работать в довольно ограниченных средах (то есть в старых дистрибутивах Linux с минимальным количеством программ), я не могу полагаться на функции, представленные в C ++ 11 и более поздних версиях (например, умные указатели )), и я до сих пор придерживался сочетания навыков программирования на C и Java при расширении своей программы. Среди прочего, я довольно часто использовал динамическое распределение с new и delete - что, конечно, является проблемой.

Чтобы облегчить обслуживание моего кода будущими программистами, яхотел бы свести к минимуму динамическое распределение с указанными ключевыми словами в моем коде. Проблема в том, что моя программа должна управлять некоторыми довольно большими структурами данных, используемыми (почти) для всего выполнения. Как следствие, я изо всех сил пытаюсь выяснить, почему я должен избегать динамического выделения в этих ситуациях.

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

  • Является ли динамическое размещение объекта с new все еще плохой практикой в ​​данном конкретном контексте? Какие есть лучшие альтернативы?

  • Предположим, теперь я где-то в своей программе создаю экземпляр нового объекта без использования new, выполняю над ним некоторые операции, которые могут немного изменить его размер, затем используюспособ вставить его в мою структуру данных. Как это работает с памятью, если используется автоматическое распределение (как упоминалось здесь )?

Большое спасибо заранее.

Ответы [ 2 ]

1 голос
/ 16 октября 2019

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

https://www.boost.org/doc/libs/1_71_0/libs/smart_ptr/doc/html/smart_ptr.html

Они очень похожи на интеллектуальные указатели C ++ 11, но доступны в виде библиотеки, которая должна работать в средах, предшествующих C ++ 11,Если вы решите пойти по этому пути, вы также можете посмотреть на это

Как включить в проект только коды интеллектуальных указателей BOOST?

Теперь яМне интересно, если вы путаете функции new / delete с динамическим размещением в целом. Умные указатели по-прежнему динамически распределяются, однако они способны очистить себя, так что вам не придется помнить тоже. Вот почему они предпочтительнее, чем использование new / delete (malloc / free и т. Д.), Они гораздо реже приводят к утечкам памяти.

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

0 голосов
/ 16 октября 2019

Является ли динамическое размещение объекта с new все еще плохой практикой в ​​этом конкретном контексте?

Да, плохо иметь new в вашем коде, главным образом из-заутечки памяти, если не вызывается delete или delete[], особенно при наличии исключений.

Какие есть лучшие альтернативы?

Пишите умные указатели ипусть они либо сами вызовут new, либо вызовутся с выражением new:

myUniquePtr<myObj> obj_ptr(new myObj);

, а затем с помощью RAII деструкторы вызовут delete или delete[].

Заставьте ваш умный указатель вести себя как голый указатель любым другим способом (перегрузка operator-> и т. Д. ). Тогда он будет работать в вашем коде с тем же синтаксисом, что и ваши необработанные указатели, не беспокоясь о том, удаляется ли объект кучи в конце его жизненного цикла, независимо от того, по каким путям может идти код.

...