![]() |
Модераторы: bsa |
![]() ![]() ![]() |
|
Compositum |
|
||||||||||||||||||||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
Язык программирования: C (не C++).
Книга: "Язык программирования C"; авторы: Брайан Керниган, Деннис Ритчи (второе издание). Потихоньку, не торопясь, последовательно, на совесть выполняю все упражнения книги... Сейчас выполняю упражнение 1.16 из раздела 1.9. (хотя прочитал намного дальше...).
Мои размышления идут по такому пути: строка представляет собой массив объектов char, т.о., теоретически, самый простой вариант отведения необходимого объёма памяти - изначально создать массив char, имеющий максимально допустимую длину - тогда в неё поместится любая возможная строка. Это, конечно, неправильный подход, поскольку получается, что под какую-то единственную строку я могу запросить столько памяти, сколько на моей машине даже физически нет... Но, всё таки любопытно посмотреть, что из этого получится... В разделе 1.6 "Массивы" обозначенной мною книги есть такая фраза:
Из этого текста я делаю вывод, что в качестве размера массива я смогу задать значения таких типов как int, unsigned int, long int, unsigned long int. Проверяю предположение:
Результат:
Как видим - компиляция проходит успешно, а значит - перехожу к следующей стадии своей страшной затеи и сразу же беру быка за рога:
Результат:
Слишком большое... Хорошо, понижаю планку:
Результат:
Как видим, сообщение несколько изменилось, однако результат по прежнему отрицательный... Снова понижаю планку:
Результат:
Как видим - в этот раз компиляция прошла успешно, однако в процессе выполнения получаю ошибку. Из краткого сообщения, делаю предположение, что размер строки не может быть больше размера сегмента. Т.о. мои опасения на тему того, что теоретически я могу отдать под массив char памяти больше, чем у меня есть физически - не оправдались (и слава Богу ![]() У меня 64-х разрядная операционная система (Ubuntu 11.04). Как можно программно (на C) получить размер сегмента (я так понимаю, что речь о сегменте памяти)? Правильно ли я понимаю, что под условие задачи (насчёт строки любой длины) я должен задавать размер массива char, равный размеру сегмента памяти (видимо разделение одной строки по нескольким сегментам не допустимо)? Спасибо. |
||||||||||||||||||||
|
|||||||||||||||||||||
volatile |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 2107 Регистрация: 7.1.2011 Репутация: 16 Всего: 85 |
Скорей всего там вообще не надо отводить память. Если это входной поток, возможно нужно просто считать на лету. Покажите о каком главном модуле, идет речь. |
|||
|
||||
Compositum |
|
|||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
На данный момент мне быстрее показать скрин, чем набирать исходники (иначе на работу опоздаю) - выложил его здесь. Да, это входной поток, но в примере, прежде чем читать его, создаётся переменная longest (массив char, размером 1000). Я так понял, что вместо 1000 нужно подставить др. число, максимально допустимое для длины строки в потоке - вот я и пытался сделать это в первом сообщении топика... |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Compositum, ты пытаешься найти решение несуществующей проблемы.
Допустим, у тебя есть строка какого-то размера (он заранее не известен), тебе гарантированно нужно сделать ее копию. Для этого достаточно воспользоваться циклом, realloc и методом выделения памяти, используемом в std::vector - размер выделенной памяти должен быть в 2 раза больше, чем было до этого. Таким образом, если по умолчанию ты будешь делать буфер размером 128 байт, то тебе понадобится всего 3 перевыделения, чтобы получить размер 1024 (128->256->512->1024). |
|||
|
||||
Compositum |
|
|||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
Я всего лишь последовательно выполняю упражнения. На той стадии, на которой находится обозначенная задача, авторами книги ещё не были обозначены никакие realloc и std::vector (повторюсь - это C, а не C++). Исходя из этого, я предполагаю, что авторы книги (они же и авторы языка C), подразумевают какой-то др. способ, доступный читателю на основе ранее изложенного материала... |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Compositum, сделай так, чтобы если getline достигла лимита буфера, то она не ставила конец строки. Таким образом ты сможешь отследить этот момент и корректно вывести и строку, и ее размер. Хранить всю строку в памяти смысла нет никакого.
|
|||
|
||||
Compositum |
|
|||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
Но если строка выйдет за границы буфера (т.е. по сути - стека), то она начнёт писать данные поверх кода, стирая его... Или я ошибаюсь? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
Compositum, читать надо кусочками. Прочитал кусок строки размером в MAXLEN, вывел, прочитал другой, тоже вывел, ... прочитал конец, вывел, вывел размер.
Это по сути тоже самое, что читать посимвольно и сразу выводить на экран. |
|||
|
||||
Compositum |
|
|||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
Стоп. Хорошо, вот начну я выводить, и вдруг окажется, что следующее слово будет ещё длиннее, а я уже "навыводил"... Тогда как? Я ведь смотрю в разрезе задачи, код которой показан мною на скрине, а в ней требуется из массива строк, поступающего на входе, выбрать самую большую... Это сообщение отредактировал(а) Compositum - 31.5.2011, 06:32 |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
||||
|
||||
Compositum |
|
|||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
Я так понял, что показанный мною выше скрин ты не смотрел... ![]() На нём в комментарии, перед main() озвучена решаемая задача: вывод самой длинной строки в потоке. На том же скрине, в самом низу след. страницы видно задание (упр. 1.16), о котором я собственно и пишу ![]() ![]() Вот я и думаю, как зная только массивы, суметь обработать входной поток любого размера и вывести строку любой длины, насколько это позволяет текст (главный модуль - это код, показанный на стр. 42 моего скрина). Я не понял фразы "насколько это позволяет текст"... Ведь текст - это массив символов. Массиву можно назначить далеко не каждый размер (это я показал в первом сообщении топика). Как правильно определить максимально возможный размер массива для того или иного типа данных? |
|||
|
||||
bsa |
|
|||
![]() Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Модератор Сообщений: 9185 Регистрация: 6.4.2006 Где: Москва, Россия Репутация: 85 Всего: 196 |
скрин я смотрел, но не читал все.
Перечитал все. Я не знаю решения задачи, без использования динамических массивов. Если бы речь шла о чтении файла, то можно было бы решить путем сохранения позиции максимальной строки в файле. Возможно, в книге ошибка. |
|||
|
||||
Compositum |
|
|||
![]() Senior developer ![]() ![]() Профиль Группа: Awaiting Authorisation Сообщений: 430 Регистрация: 6.1.2008 Где: Санкт-Петербург Репутация: нет Всего: 1 |
а я уж было подумал, что это я такой тупой, не могу простую задачку решить (сложную авторы вряд ли выложили бы на этой стадии)... ![]() Это сообщение отредактировал(а) Compositum - 31.5.2011, 18:53 |
|||
|
||||
xvr |
|
|||
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Комодератор Сообщений: 7046 Регистрация: 28.8.2007 Где: Дублин, Ирландия Репутация: 35 Всего: 223 |
Неправильный вывод (пока оставим за бортом вопрос о существовании сегментов вообще). Твой массив расположен в стеке, вот именно он и переполнился. Сделай массив глобальным (объяви перед main) |
|||
|
||||
Dov |
|
|||
![]() аСинизатор ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1721 Регистрация: 10.5.2003 Где: Эрец-Исраэль Репутация: 11 Всего: 88 |
В оригинале задача выглядит так: Revise the main routine of the longest-line program so it will correctly print the length of arbitrarily long input lines, and as much as possible of the text.
В моём (не совершенном) переводе это может звучать так: Исправьте функцию main программы так, что бы она корректно выводила длину(т.е. количество символов) самой длинной строки и, как можно большее количество текста(ограниченное, как мы помним, значением MAXLINE). Это сообщение отредактировал(а) Dov - 1.6.2011, 17:46 -------------------- Тут вечности запах томительный, И свежие фрукты дешевые, А климат у нас – изумительный, И только соседи – #уевые. Игорь Губерман. |
|||
|
||||
![]() ![]() ![]() |
Правила форума "C/C++: Для новичков" | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
0 Пользователей: | |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |