Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Заблокирован

Как выделяется память под массив string?

11.09.2012, 12:55. Показов 34194. Ответов 28
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
В общем читаю книжку, там объявлены два массива int* p = new int[10], int* v = new string[10]... бла бла бла ....а потом -> ...После резервирования области памяти, предназначенной для хранения объектов...и тут загвоздка, ну с integer все понятно, а как выделяется под string память? я же могу ввести один символ "а"\0 а могу целый файл туда в string затолкать, строк эдак на 1000 ....куда бедный указатель будет указывать после приращения ++v ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
11.09.2012, 12:55
Ответы с готовыми решениями:

Почему не выделяется память под двумерный массив?
**ptrarray = new float* ; for (int i = 0; i < h; i++){ ptrarray = new float ; } Пишет: Вызвано исключение:...

Объясните как выделяется память под умные указатели
Читаю книгу Праты, не могу понять этот абзац, а точнее применение операторов new и new и delete и delete с ними. Почему нельзя...

Рекурсия: как выделяется память под рекурсивный вызов?
на картинке файлик из википедии в которой говорится что рекусия имеет вид дерева и некоторые ветви могут вычислятся по многу раз. А как это...

28
Делаю внезапно и красиво
Эксперт С++
 Аватар для Deviaphan
1313 / 1228 / 72
Регистрация: 22.03.2011
Сообщений: 3,744
11.09.2012, 13:05
Цитата Сообщение от AnreyKazakov Посмотреть сообщение
int* v = new string[10]
Это не скомпилируется.
1
 Аватар для Кот Ангенс
320 / 270 / 128
Регистрация: 24.05.2012
Сообщений: 629
11.09.2012, 13:07
Указатель будет указывать куда надо, потому что в string есть свой указатель (или указатели), управляющие памятью. В том и суть, чтобы программист перестал об этом думать.

Добавлено через 1 минуту
Цитата Сообщение от Deviaphan Посмотреть сообщение
Это не скомпилируется.
Кстати, да.
C++
1
string* s = new string[10];
1
Заблокирован
11.09.2012, 13:20  [ТС]
Цитата Сообщение от Deviaphan Посмотреть сообщение
Это не скомпилируется
Ну, подумаешь ошибся, суть то не в этом была... =)
0
545 / 344 / 12
Регистрация: 05.11.2010
Сообщений: 1,076
Записей в блоге: 1
11.09.2012, 14:09
Ну, подумаешь ошибся, суть то не в этом была... =)
Нифига себе "подумаешь ошибся", начни с изучения типизации C++, а потом за указатели берись :-)
Если речь о std::string из stl, внутри имеется свой динамический массив, кем он управляется - дело десятое, есть какой-то аллокатор, наверняка как в векторе резервируется память заранее.
0
154 / 138 / 34
Регистрация: 23.05.2009
Сообщений: 275
11.09.2012, 14:14
Память резервируется по мере необходимости. Если памяти меньше чем необходимо для выполнения операции (например, при конкатенации), то происходит выделение памяти необходимого размера. В некоторых случаях для того, чтобы избежать многократных операций выделения памяти и копирования нужно использовать метод reserve. Вот небольшой синтетический пример, где можно избежать этих выделений и копирований:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;
 
int main()
{
   string str;
   string appendStr = "string to append";
   const int APP_TIMES = 20;
   cout<<"New created string capacity: "<<str.capacity()<<'\n';
   
//  str.reserve(str.size() + APP_TIMES * appendStr.size());
//  cout<<"Reserved memory for elements. Capacity: "<<str.capacity()<<'\n';   
   
   for(int i = 0; i < APP_TIMES; ++i)
   {
      str += appendStr;
      cout<<"appending '"<<appendStr<<"' to str. capacity: "<<str.capacity()<<'\n';
   } 
      
   return 0;
}
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
11.09.2012, 17:30
На сколько я понял ТС не про это спрашивал. Вопрос был про new std::string[10], типа откуда компилятор знает, сколько памяти выделять, ведь строки могут быть разных размеров.
Так вот, размер строки не имеет значения, потому как размер объекта std::string - величина постоянная (не надо путать размер объекта и размер строки).
Для примера
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
int main ()
{
    std::string str1 = "a";
    std::string str2 = "aklsdjfaklsjfdkas;fjak;lsdfjaks jfasdfj jidf joaijf klj  \
        asdkfj ajf aij fwoijowij oijf oiajefwiojf anvj knvv aoijf \
        asdfhjkashdf ajfasjf ksa;jf asodfjioasdjfiopadfjasdjfklasd;jf;asl \
        asjdfhjkaslhfdkasdljf qwjer iojfoiawjfksald;jf sakdl;jf jsaifjw[oej";
 
    std::cout << "sizeof(str1) = " << sizeof(str1) << std::endl 
              << "sizeof(str2) = " << sizeof(str2) << std::endl
              << "sizeof(std::string) = " <<  sizeof(std::string) <<  std::endl;
 
    return 0;
}
вот вывод одного из компиляторов (думаю, это компиляторозависимая величина, хотя можно в стандарт заглянуть):
Code
1
2
3
sizeof(str1) = 32
sizeof(str2) = 32
sizeof(std::string) = 32
2
 Аватар для PSIAlt
87 / 87 / 1
Регистрация: 19.06.2012
Сообщений: 245
11.09.2012, 18:16
Цитата Сообщение от Kastaneda Посмотреть сообщение
думаю, это компиляторозависимая величина, хотя можно в стандарт заглянуть
Зависимая. Некоторые реализации STL держат небольшой буффер чтобы там хранить маленькие строки без доп. выделений памяти.
Но суть верна: размер обьекта std::string == const, память которую он выделяет под саму строку выделяется отдельно в куче в конструкторе и операторе присваивания
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
11.09.2012, 22:01
Размер объекта любого типа константен, sizeof операция не времени выполнения, а времени компиляции. Размер объекта должен быть известен во время компиляции. В стандарте, на сколько мне известно, вообще не оговорены размеры объектов кроме типа char, который должен быть равен 1 байту. В частности - std::string содержит указатель на динамическую память. Размер указателя на 32 битной и 64 битной системах разный ( 4 байта и 8 байт соответственно ), поэтому размер string на этих системах будет разный.
0
Заблокирован
19.09.2012, 21:26  [ТС]
Решил погуглить на тему "c++ string как выделяется память" и напоролся на собственную тему, в прошлый раз я так и не понял ничего... Что все таки представляет собой тип string? В принципе в рамках одного элемента реально пофиг как он там будет в памяти сидеть. Интересно другое, задаешь например тип вектор, допустим, из 10 элементов string. Вот тут начинается (у меня) путаница с памятью. Вектор выделяет для себя некоторый кусок памяти. Если задать итераторы и не выполнять удаления\добавления элементов в центре контейнера то по идее они не должны менять свое значение. Воооот, тепер вопрос по string у, компилятор наверно каждому элементу стриг выделяет какой-то объем памяти, возможно, если строка превышает количество выделенного для нее "места" то объем для стринга должен увеличиться, но
1.как если элемент находится в векторе? если увеличить объем одной ячейки то итераторы будут указывать или неверно или чушь полную...
2.если увеличится объем памяти для одного стринга в векторе, то это должно повлиять и на увеличение всех остальных элементов.
В общем как не думал, у меня в башке string какая-то безразмерная величина получается...
А, понял, если string это указатель на динамическую память, то вектор string ов всего лишь контейнер с указателями... А там что творится в этой динамической памяти одному богу пожалуй известно...
1
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
19.09.2012, 21:43
Ну вроде вы на верном пути если упростить строку и считать ее указателем на символы, то примерно это выглядит так:

C++
1
2
3
4
[s   s    s    s    s  ...   s] - это указатели на массивы байт, в которых хранятся символы строки. размер указателей фиксированный
     |              |
     |              |
    ["dfsdf"]    ["sdfsfsfsdfsfsfsfsfsfsfsd"]  -  a это то, на что эти указатели указывают.
Т.е. для выделения 10 строк в массиве нужно вполне конкретное количество байтов памяти, равное N = sizeof(std::string) * 10, и то, что внутри себя эти std::string указывают на область памяти любого размера не влияют на это число N.
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
19.09.2012, 21:47
String это класс, точнее синоним для
C++
1
basic_string< char >
. Поэтому в векторе хранятся объекты класса, а не указатели.
0
DU
1500 / 1146 / 165
Регистрация: 05.12.2011
Сообщений: 2,279
19.09.2012, 21:52
ну понятно что не указатели, а объекты. для упрощения было принято, что эти объекты представляют из себя некую оболочку над указателями, или просто указатели. ведь что внутри строки? указатель на буфер + какие-то дополнительные члены для чего-нибудь.
0
 Аватар для Toshkarik
1181 / 894 / 94
Регистрация: 03.08.2011
Сообщений: 2,461
19.09.2012, 22:03

Не по теме:

DU, эт я ТСу :)


Цитата Сообщение от DU Посмотреть сообщение
ведь что внутри строки?
Там может быть все что угодно Это ведь не оговорено нигде.
0
just_lexx
21.02.2014, 18:48
Серьезно задался вопросом сколько памяти займет одно использование переменной типа string. Однозначного ответа не нашел. Нашел не очень понятный мне отрывок из книги.

Совет 15:
http://cpp.com.ru/meyers/ch2.html#t30

Но вероятно он может частично дать ответ на вопрос автора.
0 / 0 / 0
Регистрация: 04.09.2017
Сообщений: 1
04.09.2017, 00:24
Чтобы не париться по поводу выделения памяти в string, можно создать массив строк более простым способом.
Опишем тип - структура.

C++
1
2
3
struct myString{
    char s[100];
};
Создадим динамический массив строк, заполним его элементы, удалим после использования.

C++
1
2
3
4
5
6
7
myString * arr = new myString[10];
 
for(int i = 0; i < 10; i++){
     strcpy(arr[i].s, "hello world");
}
 
delete [] arr;
0
Эксперт С++
 Аватар для hoggy
8973 / 4319 / 960
Регистрация: 15.11.2014
Сообщений: 9,760
04.09.2017, 02:33
Цитата Сообщение от maxim218218 Посмотреть сообщение
Чтобы не париться по поводу выделения памяти в string
нужно просто брать string,
пользоваться в своё удовольствие,
и не забивать себе голову ручной работой с new/delete

а не заниматься всякой фигней навроде:
Цитата Сообщение от maxim218218 Посмотреть сообщение
myString * arr = new myString[10];
Цитата Сообщение от maxim218218 Посмотреть сообщение
delete [] arr;
0
 Аватар для Cobarg
0 / 0 / 0
Регистрация: 19.02.2020
Сообщений: 15
27.02.2025, 14:36
Действительно. Вот такой вопрос: если создать std::vector <string> S и начать вносить в него элементы, где первый элемент 1 символ, второй 200 символов, третий 10000. Используя string мы сэкономим память? Просто набрал программку и она показывает, что каждый элемент string в vector занимает 32 бита (на моей ОС). Получается оптимизации памяти нет? И лучше работать с указателями, new и delete, чтобы под каждый отдельный элемент подбирать размер. Например, как тут:
C++
1
2
3
4
5
6
7
8
9
char *getname(void)
{
    char temp[100];
    cout<<"Enter name: ";
    cin>>temp;
    char *pntTemp = new char[strlen(temp)+1];
    strcpy(pntTemp,temp);
    return pntTemp;
}
Но тогда новый вопрос: vector позволяет, чтобы элементы в одном массиве были разной величины или все одно даст общий размер?

Если все так, то наиболее оптимальный вариант для экономии памяти это *, new, delete и массив char?

Спасибо всем кто ответит.
0
Вездепух
Эксперт CЭксперт С++
 Аватар для TheCalligrapher
12933 / 6801 / 1820
Регистрация: 18.10.2014
Сообщений: 17,213
27.02.2025, 15:46
Цитата Сообщение от Cobarg Посмотреть сообщение
Используя string мы сэкономим память?
"Сэкономим"? Что вы имеете в виду? Сэкономим по сравнению с чем?

Цитата Сообщение от Cobarg Посмотреть сообщение
Просто набрал программку и она показывает, что каждый элемент string в vector занимает 32 бита (на моей ОС).
"Бита"??? Может "байта"?

32 байта - нормально для std::string.

Цитата Сообщение от Cobarg Посмотреть сообщение
Получается оптимизации памяти нет?
О чем речь? Какой "оптимизации памяти" (которой "нет") вы ожидали? В чем проблема?

Цитата Сообщение от Cobarg Посмотреть сообщение
Например, как тут:
Но тут одна строка, а в std::vector<std::string> - это много строк. То есть это совершенно не сравнимые примеры. Так о чем вы говорите? Об одной строке или о "много строк"?

Цитата Сообщение от Cobarg Посмотреть сообщение
vector позволяет, чтобы элементы в одном массиве были разной величины или все одно даст общий размер?
Вектор - это оболочка над обычным языковым массивом. Элементы массива в С и С++ всегда обязательно имеют один и тот же размер. Не бывает массивов с элементами разного размера.

Цитата Сообщение от Cobarg Посмотреть сообщение
Если все так, то наиболее оптимальный вариант для экономии памяти это *, new, delete и массив char?
Ничего не понятно. Изначально вы говорили о std::vector<std::string>, то есть о массиве строк. Ну так покажите, как вы собрались делать массив строк при помощи "new, delete и массив char". Тогда и полноценно сравнивать что-то можно будет.
0
 Аватар для SmallEvil
4086 / 2975 / 813
Регистрация: 29.06.2020
Сообщений: 11,000
27.02.2025, 16:00
Цитата Сообщение от Cobarg Посмотреть сообщение
если создать std::vector <string> S и начать вносить в него элементы, где первый элемент 1 символ, второй 200 символов, третий 10000. Используя string мы сэкономим память?
Что значит "сэкономим"?
Будет использован объем равен одному вектору типа string и трем стрингам различной длинны.
В некоторых случаях с SSO (Short String Optimization) - размер может быть другим, немного.

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
#include <vector>
#include <string>
 
int main(){
    std::vector<std::string> v{std::string(1, 'a'), std::string(200, 'a'), std::string(1000, 'a') };
    unsigned total_size = 0;
    total_size += sizeof(v);
    total_size += sizeof(std::vector<std::string>::value_type)*v.capacity();
    std::cout << "Basic size of vector : " << total_size << std::endl;
    for(unsigned i = 0; i < v.size(); ++i){
       using char_type = std::string::value_type;
       total_size += sizeof(char_type) * v[i].size();
    }
    std::cout << "Using of memory by vector : " << total_size << " bytes." << std::endl;
}
Возможный вывод:
Code
1
2
Basic size of vector : 120
Using of memory by vector : 1321 bytes.
Добавлено через 6 минут
Цитата Сообщение от SmallEvil Посмотреть сообщение
C++
13
total_size += sizeof(char_type) * v[i].size();
И для объективности, тут тоже нужно брать capacity(), а не size().

Добавлено через 1 минуту
И вывод уже немного другой :
Code
1
2
Basic size of vector : 120
Using of memory by vector : 1335 bytes.
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
27.02.2025, 16:00
Помогаю со студенческими работами здесь

Как выделяется память на стеке и на куче? Когда нужна ручная очистка?
Всем здрасьте. //1 char s = 's'; //2 char* ss = new char; Во втором случае компилятор выделяет участок памяти, потом мне же её...

Как выделить память под массив в структуре?
Здравствуйте , воnрос конечно глуnый , но голову я сижу ломаю долго , есть Структура , в ней есть массив , как nод этот массив выделить...

Как выделить память под динамический двумерный массив
Добрый день, достаточно простой вопрос, но почему-то он возник, и нагуглить ответ я не смог. Обычно выделял память под двумерный массив...

Как правильно выделить память под двумерный массив в шаблоне?
template &lt;class T&gt; T* array &lt;T&gt;::f (unsigned size) { //...... T* templateBuf = new T ; for (unsigned index = 0;...

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


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 28.01.2026
Содержание блога SDL3 имеет собственные средства для загрузки и отображения PNG-файлов с альфа-каналом и базовой работы с ними. В этой инструкции используется функция SDL_LoadPNG(), которая. . .
Загрузка PNG с альфа-каналом на SDL3 для Android: с помощью SDL3_image
8Observer8 27.01.2026
Содержание блога SDL3_image - это библиотека для загрузки и работы с изображениями. Эта пошаговая инструкция покажет, как загрузить и вывести на экран смартфона картинку с альфа-каналом, то есть с. . .
влияние грибов на сукцессию
anaschu 26.01.2026
Бифуркационные изменения массы гриба происходят тогда, когда мы уменьшаем массу компоста в 10 раз, а скорость прироста биомассы уменьшаем в три раза. Скорость прироста биомассы может уменьшаться за. . .
Воспроизведение звукового файла с помощью SDL3_mixer при касании экрана Android
8Observer8 26.01.2026
Содержание блога SDL3_mixer - это библиотека я для воспроизведения аудио. В отличие от инструкции по добавлению текста код по проигрыванию звука уже содержится в шаблоне примера. Нужно только. . .
Установка Android SDK, NDK, JDK, CMake и т.д.
8Observer8 25.01.2026
Содержание блога Перейдите по ссылке: https:/ / developer. android. com/ studio и в самом низу страницы кликните по архиву "commandlinetools-win-xxxxxx_latest. zip" Извлеките архив и вы увидите. . .
Вывод текста со шрифтом TTF на Android с помощью библиотеки SDL3_ttf
8Observer8 25.01.2026
Содержание блога Если у вас не установлены Android SDK, NDK, JDK, и т. д. то сделайте это по следующей инструкции: Установка Android SDK, NDK, JDK, CMake и т. д. Сборка примера Скачайте. . .
Использование SDL3-callbacks вместо функции main() на Android, Desktop и WebAssembly
8Observer8 24.01.2026
Содержание блога Если вы откроете примеры для начинающих на официальном репозитории SDL3 в папке: examples, то вы увидите, что все примеры используют следующие четыре обязательные функции, а. . .
моя боль
iceja 24.01.2026
Выложила интерполяцию кубическими сплайнами www. iceja. net REST сервисы временно не работают, только через Web. Написала за 56 рабочих часов этот сайт с нуля. При помощи perplexity. ai PRO , при. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru