Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.67
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
01.06.2013, 18:29     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) #1
Добрый день. Как осуществляется выделения памяти под перегруженный оператор ввода данных в пользовательский тип? Ведь мы заранее не можем знать сколько в действительности может понадобиться памяти. Если у кого-то есть соображения по этому поводу, поделитесь, пожалуйста.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.06.2013, 18:29     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &)
Посмотрите здесь:

C++ cannot convert parameter 1 from 'int' to 'std::string &'
C++ Какая роль std::istream::sentry
Ошибка: отсутствует оператор ">>"; типы операндов: std::istream >> std::string C++
std::istream часть кода C++
Поясните синтаксис - ( std::string& x: bar ) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт С++
 Аватар для Croessmah
11832 / 6811 / 769
Регистрация: 27.09.2012
Сообщений: 16,885
Записей в блоге: 2
Завершенные тесты: 1
01.06.2013, 18:39     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) #2
Можно считывать по символу(или сразу по нескольку символов) и помещать их в строку с помощью функций членов класса String. Надеюсь, что в классе есть механизм перераспределения памяти.
Потом смотрим входной поток. Если в нем еще что-то есть, то повторяем операцию. И так до конца, либо до символа-разделителя.
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
01.06.2013, 19:20  [ТС]     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) #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 - проще.
gray_fox
What a waste!
 Аватар для gray_fox
1244 / 1127 / 53
Регистрация: 21.04.2012
Сообщений: 2,350
Завершенные тесты: 3
01.06.2013, 19:46     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) #4
xtorne21st, если String::operator = выкинет исключение, то будет утечка памяти.
Tulosba
:)
Эксперт С++
4378 / 3221 / 297
Регистрация: 19.02.2013
Сообщений: 9,044
01.06.2013, 22:23     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) #5
Задача написать свой string что ли? Так пройдитесь отладчиком по стандартному std::istream >> std::string. Многое прояснится.
OhMyGodSoLong
~ Эврика! ~
 Аватар для OhMyGodSoLong
1234 / 983 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
02.06.2013, 01:36     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) #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 или применяют более хитрую стратегию роста.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
02.06.2013, 03:24     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &)
Еще ссылки по теме:

Friend ostream& operator<<(ostream& stream, CArr& obj); C++
Error: cannot bind 'std::basic_ostream<wchar_t>' lvalue to 'std::basic_ostream<wchar_t>&&'| C++
C++ Std::istream::tellg нумерация символов

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

Или воспользуйтесь поиском по форуму:
xtorne21st
интересующийся
300 / 271 / 19
Регистрация: 25.09.2010
Сообщений: 1,056
02.06.2013, 03:24  [ТС]     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &) #7
Всё так и сделал как вы сказали - помогло.
Yandex
Объявления
02.06.2013, 03:24     Выделение памяти для буффера, под std::istream& operator>>(std::istream &, String &)
Ответ Создать тему
Опции темы

Текущее время: 12:22. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru