интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
1

Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &)

01.06.2013, 18:29. Показов 3128. Ответов 6
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Добрый день. Как осуществляется выделения памяти под перегруженный оператор ввода данных в пользовательский тип? Ведь мы заранее не можем знать сколько в действительности может понадобиться памяти. Если у кого-то есть соображения по этому поводу, поделитесь, пожалуйста.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
01.06.2013, 18:29
Ответы с готовыми решениями:

Parse_matrix(std::istream& in); std::istream& in что это значит?
Есть функция которую необходимо описать: std::pair<int, int> parse_matrix(std::istream& in){ ...

Ошибка: multiple definition of `void std::swap<A>(A&amp;, A&amp;)
Хочу специализировать swap для своего класса. Получаю ошибку. Вот код:#ifndef A_H #define A_H ...

Undefined reference to Rhombus::Rhombus(std::istream &)
Доброго времени суток. При компиляции в чистом g++ возникли три похожие ошибки, аналогичные той,...

Странная ошибка: [Error] no match for call to '(std::string {aka std::basic_string<char>}) (int&)'
У меня появляется проблема при компиляции сей программы: #include &lt;iostream&gt; #include &lt;string&gt;...

6
Неэпический
18093 / 10680 / 2060
Регистрация: 27.09.2012
Сообщений: 26,880
Записей в блоге: 1
01.06.2013, 18:39 2
Можно считывать по символу(или сразу по нескольку символов) и помещать их в строку с помощью функций членов класса String. Надеюсь, что в классе есть механизм перераспределения памяти.
Потом смотрим входной поток. Если в нем еще что-то есть, то повторяем операцию. И так до конца, либо до символа-разделителя.
1
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
01.06.2013, 19:20  [ТС] 3
Что-то ничего умней придумать не удалось:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
std::istream& operator>>(std::istream& stream, String& x)
{
    int i, size = 1;
    char* buff = (char*)malloc(size++);
    char ch;
 
    for (i = 0; stream.get(ch) && ch != '\n' ; ++i)
    {
        buff[i] = ch;
        buff = (char*)realloc(buff, size++);
    }
    if (i != 0)
    {
        buff[i] = 0;
        x = buff;
    }
 
    free(buff);
    return stream;
}
как мне кажется, этот вариант не очень удачный, так как используется вместо new функция malloc/realloc. А иначе можно б было создать вспомогательный конструктор для внутреннего объекта класса String (так как он в качестве деструктора использует оператор delete, а не free()) и просто присвоить текущему указателю новый объект, и не прибегать к вызову перегруженного оператора =, который заново выделяет память. Хотя с другой стороны постоянное выделения новой памяти и перекопирование старого значения в новую память также расходная операция и ко всему прочему реализация при помощи malloc/realloc - проще.
0
What a waste!
1610 / 1302 / 180
Регистрация: 21.04.2012
Сообщений: 2,733
01.06.2013, 19:46 4
xtorne21st, если String::operator = выкинет исключение, то будет утечка памяти.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
01.06.2013, 22:23 5
Задача написать свой string что ли? Так пройдитесь отладчиком по стандартному std::istream >> std::string. Многое прояснится.
1
~ Эврика! ~
1257 / 1006 / 74
Регистрация: 24.07.2012
Сообщений: 2,002
02.06.2013, 01:36 6
Цитата Сообщение от xtorne21st Посмотреть сообщение
Хотя с другой стороны постоянное выделения новой памяти и перекопирование старого значения в новую память также расходная операция и ко всему прочему реализация при помощи malloc/realloc - проще.
realloc() тоже будет копировать память, если у него закончится свободное место сразу же за расширяемым куском.

Как это делается правильно:
1. String всегда выделяет память с запасом.
2. Читаем символ из потока в следующую ячейку буфера.
3. Если символы в потоке закончились, то выходим.
4. Если нет, и буфер ещё не закончился, то goto 2.
5. Если символы так и прут, а буфера уже нет, то
5.1. Выделяем в K раз больше памяти, чем есть сейчас.
5.2. Копируем/перемещаем туда всё, что есть сейчас.
5.3. Освобождаем ненужную старую память.
5.4. goto 2.

Константу K обычно берут в районе 1,5 — 2 или применяют более хитрую стратегию роста.
1
интересующийся
311 / 282 / 93
Регистрация: 25.09.2010
Сообщений: 1,056
02.06.2013, 03:24  [ТС] 7
Всё так и сделал как вы сказали - помогло.
0
02.06.2013, 03:24
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
02.06.2013, 03:24
Помогаю со студенческими работами здесь

Error C2664: std::vector<_Ty>::push: невозможно преобразовать параметр 1 из 'double' в 'const std::string &'
#include &lt;iostream&gt; #include &lt;stack&gt; #include &lt;sstream&gt; #include &lt;string&gt; using namespace...

Ошибка: отсутствует оператор ">>"; типы операндов: std::istream >> std::string
Привет всем! Кто-нибудь объясните пожалуйста, что не так, что от меня компилятор требует?

Почему friend ostrem& operator <<(ostream& outs, const Rational&); - invalid function declaration?
Пытаюсь скомпилировать программу пишет friend ostrem&amp; operator &lt;&lt;(ostream&amp; outs, const...

Ошибка undefined reference to `operator<<(std::ostream&, Account)'
Всем здравствуйте! На днях столкнулся с ошибкой, с которой еще не раз не сталкивался, и не знаю как...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru