Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
AnreyKazakov
Заблокирован
#1

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

11.09.2012, 12:55. Просмотров 7819. Ответов 16
Метки нет (Все метки)

В общем читаю книжку, там объявлены два массива int* p = new int[10], int* v = new string[10]... бла бла бла ....а потом -> ...После резервирования области памяти, предназначенной для хранения объектов...и тут загвоздка, ну с integer все понятно, а как выделяется под string память? я же могу ввести один символ "а"\0 а могу целый файл туда в string затолкать, строк эдак на 1000 ....куда бедный указатель будет указывать после приращения ++v ?
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
11.09.2012, 12:55
Я подобрал для вас темы с готовыми решениями и ответами на вопрос Как выделяется память под массив string? (C++):

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

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

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

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

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

Ввод значения в переменную типа string, память под которую выделена динамически - C++
Ребят, подскажите пожалуйста, как организовать ввод значения в переменную типа string, память под которую выделена динамически? ...

16
Deviaphan
Делаю внезапно и красиво
Эксперт С++
1306 / 1221 / 50
Регистрация: 22.03.2011
Сообщений: 3,744
11.09.2012, 13:05 #2
Цитата Сообщение от AnreyKazakov Посмотреть сообщение
int* v = new string[10]
Это не скомпилируется.
0
Кот Ангенс
318 / 268 / 38
Регистрация: 24.05.2012
Сообщений: 629
11.09.2012, 13:07 #3
Указатель будет указывать куда надо, потому что в string есть свой указатель (или указатели), управляющие памятью. В том и суть, чтобы программист перестал об этом думать.

Добавлено через 1 минуту
Цитата Сообщение от Deviaphan Посмотреть сообщение
Это не скомпилируется.
Кстати, да.
C++
1
string* s = new string[10];
1
AnreyKazakov
Заблокирован
11.09.2012, 13:20  [ТС] #4
Цитата Сообщение от Deviaphan Посмотреть сообщение
Это не скомпилируется
Ну, подумаешь ошибся, суть то не в этом была... =)
0
Герц
524 / 341 / 4
Регистрация: 05.11.2010
Сообщений: 1,077
Записей в блоге: 1
11.09.2012, 14:09 #5
Ну, подумаешь ошибся, суть то не в этом была... =)
Нифига себе "подумаешь ошибся", начни с изучения типизации C++, а потом за указатели берись :-)
Если речь о std::string из stl, внутри имеется свой динамический массив, кем он управляется - дело десятое, есть какой-то аллокатор, наверняка как в векторе резервируется память заранее.
0
Andsteadur
153 / 137 / 3
Регистрация: 23.05.2009
Сообщений: 275
11.09.2012, 14:14 #6
Память резервируется по мере необходимости. Если памяти меньше чем необходимо для выполнения операции (например, при конкатенации), то происходит выделение памяти необходимого размера. В некоторых случаях для того, чтобы избежать многократных операций выделения памяти и копирования нужно использовать метод 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
Jesus loves me
Эксперт С++
4749 / 2953 / 242
Регистрация: 12.12.2009
Сообщений: 7,491
Записей в блоге: 2
Завершенные тесты: 1
11.09.2012, 17:30 #7
На сколько я понял ТС не про это спрашивал. Вопрос был про 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;
}
вот вывод одного из компиляторов (думаю, это компиляторозависимая величина, хотя можно в стандарт заглянуть):
Код
sizeof(str1) = 32
sizeof(str2) = 32
sizeof(std::string) = 32
2
PSIAlt
87 / 87 / 8
Регистрация: 19.06.2012
Сообщений: 245
11.09.2012, 18:16 #8
Цитата Сообщение от Kastaneda Посмотреть сообщение
думаю, это компиляторозависимая величина, хотя можно в стандарт заглянуть
Зависимая. Некоторые реализации STL держат небольшой буффер чтобы там хранить маленькие строки без доп. выделений памяти.
Но суть верна: размер обьекта std::string == const, память которую он выделяет под саму строку выделяется отдельно в куче в конструкторе и операторе присваивания
0
Toshkarik
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
11.09.2012, 22:01 #9
Размер объекта любого типа константен, sizeof операция не времени выполнения, а времени компиляции. Размер объекта должен быть известен во время компиляции. В стандарте, на сколько мне известно, вообще не оговорены размеры объектов кроме типа char, который должен быть равен 1 байту. В частности - std::string содержит указатель на динамическую память. Размер указателя на 32 битной и 64 битной системах разный ( 4 байта и 8 байт соответственно ), поэтому размер string на этих системах будет разный.
0
AnreyKazakov
Заблокирован
19.09.2012, 21:26  [ТС] #10
Решил погуглить на тему "c++ string как выделяется память" и напоролся на собственную тему, в прошлый раз я так и не понял ничего... Что все таки представляет собой тип string? В принципе в рамках одного элемента реально пофиг как он там будет в памяти сидеть. Интересно другое, задаешь например тип вектор, допустим, из 10 элементов string. Вот тут начинается (у меня) путаница с памятью. Вектор выделяет для себя некоторый кусок памяти. Если задать итераторы и не выполнять удаления\добавления элементов в центре контейнера то по идее они не должны менять свое значение. Воооот, тепер вопрос по string у, компилятор наверно каждому элементу стриг выделяет какой-то объем памяти, возможно, если строка превышает количество выделенного для нее "места" то объем для стринга должен увеличиться, но
1.как если элемент находится в векторе? если увеличить объем одной ячейки то итераторы будут указывать или неверно или чушь полную...
2.если увеличится объем памяти для одного стринга в векторе, то это должно повлиять и на увеличение всех остальных элементов.
В общем как не думал, у меня в башке string какая-то безразмерная величина получается...
А, понял, если string это указатель на динамическую память, то вектор string ов всего лишь контейнер с указателями... А там что творится в этой динамической памяти одному богу пожалуй известно...
0
DU
1485 / 1131 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.09.2012, 21:43 #11
Ну вроде вы на верном пути если упростить строку и считать ее указателем на символы, то примерно это выглядит так:

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
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
19.09.2012, 21:47 #12
String это класс, точнее синоним для
C++
1
basic_string< char >
. Поэтому в векторе хранятся объекты класса, а не указатели.
0
DU
1485 / 1131 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
19.09.2012, 21:52 #13
ну понятно что не указатели, а объекты. для упрощения было принято, что эти объекты представляют из себя некую оболочку над указателями, или просто указатели. ведь что внутри строки? указатель на буфер + какие-то дополнительные члены для чего-нибудь.
0
Toshkarik
1148 / 865 / 51
Регистрация: 03.08.2011
Сообщений: 2,404
Завершенные тесты: 1
19.09.2012, 22:03 #14

Не по теме:

DU, эт я ТСу


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

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

Но вероятно он может частично дать ответ на вопрос автора.
0
21.02.2014, 18:48
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
21.02.2014, 18:48
Привет! Вот еще темы с ответами:

Не выделяется память - C++
Здравствуйте, пытаюсь выделить память, на одном компьютере работает, на другом нет, возвращает 0x00000000, хотя память имеется в наличии. В...

Выделяется ли память? - C++
Доброе время суток! У меня есть BYTE *pOutData = NULL; Объясните пожалуйста что происходит в следующем: strcpy(cToken, &quot;Задан...

Не выделяется память - C++
#include&lt;iostream&gt; #include&lt;stdio.h&gt; #include&lt;stdlib.h&gt; using namespace std; class DynArray { public: int size, end; int...

Выделяется ли память для ссылки? - C++
Добрый день есть код: char a = 'd'; char *ptr = &amp;a; char &amp;link = a; Вопрос в том, что такое link? Отдельный объект или просто...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru