Как строки выделяют память в С++?

Я знаю, что динамическая память имеет преимущества перед установкой массива фиксированного размера и использованием его части. А вот в динамическую память вам придется вводить количество данных, которое вы хотите хранить в массиве. При использовании строк вы можете ввести столько букв, сколько хотите (вы даже можете использовать строки для чисел, а затем использовать функцию для их преобразования). Этот факт заставляет меня думать, что динамическая память для символьных массивов устарела по сравнению со строками.

Итак, я хочу знать, каковы преимущества и недостатки при использовании строк? Когда место, занимаемое строками, освобождается? Может быть, возможность освободить динамически выделенную память с помощью удаления имеет преимущество перед строками? Пожалуйста, объясни.


person Stefan Stojkovski    schedule 19.08.2013    source источник
comment
Струны — это не волшебство. Это просто библиотечная функция.   -  person Kerrek SB    schedule 19.08.2013
comment
@KerrekSB: Но это все же лучше, чем использовать собственный код динамической памяти char *!   -  person Mats Petersson    schedule 19.08.2013
comment
@MatsPetersson: Да, конечно, но формулировка OP о динамически выделяемой памяти и строках является ложной дихотомией. Строки являются (обычно) динамическими контейнерами.   -  person Kerrek SB    schedule 19.08.2013
comment
Судя по всему, в двух ответах, которые я связал с вами вчера в чате, не было информации, которую вы после? Возможно, вы могли бы гораздо подробнее указать конкретный вариант использования, который вас интересует.   -  person sehe    schedule 19.08.2013


Ответы (3)


std::string обычно содержит внутренний динамически выделяемый буфер. Когда вы назначаете данные или отталкиваете новые данные, а текущего размера буфера недостаточно, выделяется новый буфер увеличенного размера, а старые данные копируются или перемещаются в новый буфер. Затем старый буфер освобождается.

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

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

person Neil Kirk    schedule 19.08.2013

Короткий ответ: «нет, нет недостатков, есть только преимущества» с std::string по сравнению с символьными массивами.

Конечно, строки ИСПОЛЬЗУЮТ динамическую память, она просто скрывает этот факт за кулисами, поэтому вам не нужно об этом беспокоиться.

Отвечая на ваш вопрос: когда освобождается пространство, занятое строками? этот пост может быть полезен. По сути, std::string освобождаются, как только они выходят за рамки. Часто компилятор может решить, когда выделять и освобождать память.

person Mats Petersson    schedule 19.08.2013

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

  • если вам нужно создать строку, содержащую предложение, то вы можете, и это нормально, не использовать malloc
  • если вам нужен массив и "поиграть" с ним, то есть изменить или установить ячейки, привязанные к какому-либо методу, или изменить его размер, тогда инициирование его с помощью malloc будет подходящим способом
  • единственная причина, по которой я вижу статическое выделение char a[17] (например), - это строка с единственной целью, которая вам нужна, то есть только тогда, когда вы знаете точный размер, который вам понадобится, и он не изменится

и один важный момент, который я нашел:

При динамическом распределении памяти, если память постоянно выделяется, а память, выделенная для неиспользуемых объектов, не освобождается, это может привести к переполнению стека или утечке памяти, что является большим недостатком.

person No Idea For Name    schedule 19.08.2013
comment
Хм? Я понятия не имею, о чем вы говорите, и, что более важно, какова цель упоминания о переполнении стека в этом конкретном контексте. - person Mats Petersson; 19.08.2013
comment
@MatsPetersson Но! Но! Stackoverflow — это круто! - person sehe; 19.08.2013