Название: Строки в стеке или в куче ? Отправлено: Etud от Март 08, 2011, 12:53 В классе My имеются символьные массивы в стеке.
Далее символьная строка (тип char) присваивается QString. Код
Как известно, существует опасность падения программы (на 20-й раз, 30-й, ...), поскольку строки большие > 200 КБ, пару строк и достигли 1MБ (предел для стека). Рекомендуют больше 1 КБ в стек не ложить. Решил в классе My выделить память в куче (т.е. создать динамические массивы). Код
Уже лучше и риск меньше ! Вопросы: 1) Строка (тип QString) увеличивает память в стеке ? 2) Под эту строку тоже отводится 200K, есть ли тут риск ? Название: Re: Строки в стеке или в куче ? Отправлено: Kolobok от Март 08, 2011, 13:15 Если объект My создан в куче, то какая разница?!
Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 08, 2011, 13:34 Да, объект my класса Му создан в куче.
Не подумал про сам объект. То есть эти массивы будут в куче, переводить их в динамику не надо ? Название: Re: Строки в стеке или в куче ? Отправлено: Stiff от Март 08, 2011, 13:48 Код
Правильнее написать так: Код Во-вторых, указатель на массив, передаваемый конструктору QString обязательно должен заканчиваться нулём, иначе возможно выхождение за пределы массива! Дабы перестраховаться, присвой последним значениям массивов нули: Код Переполнение стека не при чём, ищите ошибки. Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 08, 2011, 15:08 Тут был псевдокод. Это отработано.
Вопрос про память, чтобы краха не было. Название: Re: Строки в стеке или в куче ? Отправлено: Igors от Март 08, 2011, 16:38 Вопросы: 1) Нет (точнее на 4/8 байт независимо от размера строки)1) Строка (тип QString) увеличивает память в стеке ? 2) Под эту строку тоже отводится 200K, есть ли тут риск ? 2) Есть если Вы (нагловато) размещаете такие данные на стеке. Практичнее использовать QVector <char> (или std::vector) 3) QString сожрет вдвое больше памяти (2 байта на символ в unicode) Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 08, 2011, 19:48 Спасибо, Igors за ответ.
Конечно, QString занимает памяти вдвое больше по сравнению со строкой char-ов. Еще раз уточню задачу: Есть класс My, который имеет строку Код
Эту строку я переводил в строку QString, чтобы произвести в ней поиск (парсинг), что несомненно удобно из-за функций поиска подстрок. Слабое место у меня это массив bufBig, потому что 200К памяти отведено + еще строка QString (400К ?). Получается, что поиск (парсинг) лучше делать в массиве bufBig, что не удобно, так так надо писать свою функцию поиска. С QString это было очень удобно ! Вопросы: 1) При создании объекта my класса My в куче массив bufBig оставить без изменений (в стеке) или лучше тоже в куче ? 2) Строка Код при создании объекта my в куче размещается в стеке ? Извините, что много спрашиваю, но все 1-й раз. Название: Re: Строки в стеке или в куче ? Отправлено: Igors от Март 08, 2011, 20:06 Есть класс My, который имеет строку От этого надо (срочно) избавиться. Такое "жирное" описание никак не гуд, т.к. оно заставляет компилятор выделять стек-память впустую и без всякой необходимости. Все что "выше травы" должно быть в куче. Обычно это не вызывает затруднений., если Ваш случай особый - сообщите детали, обсудимКод
Название: Re: Строки в стеке или в куче ? Отправлено: brankovic от Март 08, 2011, 20:10 В классе My имеются символьные массивы в стеке. Код
Так они в классе или в стеке? Если объявлены как член класса, то они там, где соотв. экземпляр: Код
объект m и его поле buf будут в стеке, объект по адресу p и его поле buf будут в куче. Или имеется в виду другая конструкция? Как известно, существует опасность падения программы (на 20-й раз, 30-й, ...), поскольку строки большие > 200 КБ, пару строк и достигли 1MБ (предел для стека). Рекомендуют больше 1 КБ в стек не ложить. просто интересно, откуда данные? Я знаю, что бывают такие падения, но чтобы 1 мегабайт всего, как-то не верится. Вопросы: 1) При создании объекта my класса My в куче массив bufBig оставить без изменений (в стеке) или лучше тоже в куче ? 2) Строка Код при создании объекта my в куче размещается в стеке ? строка неявно использует буфер, который выделяется в куче. Собственно все контейнеры так устроены, если даже сам контейнер в стеке, то там хранится только указатель на буфер в куче. Не знаю, какие у вас требования по памяти, но я бы не заморачивался на счёт размера QString. В большинстве случаев ни память ни скорость для строк не критичны, а читаемость и компактность кода важны всегда. Название: Re: Строки в стеке или в куче ? Отправлено: Stiff от Март 08, 2011, 20:37 Получается, что поиск (парсинг) лучше делать в массиве bufBig, что не удобно, так так надо писать свою функцию поиска. Делай парсинг в QByteArray, функции с QString идентичныеС QString это было очень удобно ! Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 08, 2011, 21:24 Так они в классе или в стеке? Переменная-член bufBig принадлежит классу My: Код
Объект создается в куче: My *p = new My; Спасибо, значит все тут в куче. Просвятили ! Значит, если будет даже 10 объектов, память выделяется в куче, размер окна большой - ее должно хватить ? Цитата: brankovic просто интересно, откуда данные? Я знаю, что бывают такие падения, но чтобы 1 мегабайт всего, как-то не верится. Из форумов...Или не верно ? Цитата: brankovic строка неявно использует буфер, который выделяется в куче. Собственно все контейнеры так устроены, если даже сам контейнер в стеке, то там хранится только указатель на буфер в куче. В моем случае строка str используется в другом классе Tu (он в куче) Код и получает указатель на мой большой массив-буффер из класса My. Цитата: brankovic Не знаю, какие у вас требования по памяти, но я бы не заморачивался на счёт размера QString. В большинстве случаев ни память ни скорость для строк не критичны, а читаемость и компактность кода важны всегда. Да нет требований, главное чтобы пахала. Начитался флейма, а знаний про память мало. Вот и я заметил, что удобство интерфейса и поддержка кода - это много. Название: Re: Строки в стеке или в куче ? Отправлено: brankovic от Март 08, 2011, 22:09 Значит, если будет даже 10 объектов, память выделяется в куче, размер окна большой - ее должно хватить ? число объектов * размер объекта = потребление памяти. Достаточно оценить эти величины. На символ можно считать 2 байта, если кустринг. Цитата: brankovic просто интересно, откуда данные? Я знаю, что бывают такие падения, но чтобы 1 мегабайт всего, как-то не верится. Из форумов...Или не верно ?от платформы зависит, наверное. Линукс, например, по умолчанию выделяет 10 мегабайт на стек, а потом он может ещё расти. Бывают падения, если выделять очень большие куски в стеке (100 мегабайт). Толком не знаю, как там устроено. Спрашивал, потому что думал может почитать что-то есть. В моем случае строка str используется в другом классе Tu (он в куче) Код
в этом коде QString сначала посчитает размер buffer (найдёт первый '\0'), потом выделит в куче буфер такого же размера, потом скопирует всё туда. И забудет про buffer навсегда. Вообще пользоваться массивами в C-стиле нужно только ради оптимизации, и только когда точно знаешь, что делаешь. Сам всегда использую контейнеры, пока тормозить не начнёт, и обычно не начинает. Название: Re: Строки в стеке или в куче ? Отправлено: Igors от Март 09, 2011, 10:44 Код
Объект создается в куче: My *p = new My; Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 09, 2011, 10:51 Цитата: brankovic Вообще пользоваться массивами в C-стиле нужно только ради оптимизации, и только когда точно знаешь, что делаешь. Класс My это обертка вокруг С-шных функций, потому сразу не использовал QString (нельзя так). Есть класс My, который имеет строку От этого надо (срочно) избавиться. Обычно это не вызывает затруднений., если Ваш случай особый - сообщите детали, обсудим.Код
Этот буффер нужен для парсинга HTML-страницы. Оттуда дастается заголовок и другие параметры. Потому скачиваю ее полностью, дальше парсим. И вот тут уже важен алгоритм. Как можно получить эти части (нужные параметры). На лету парсить при скачке непросто. Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 09, 2011, 10:57 Нехорошо, Вас никто не заставляет распределять память немедленно и жестко (как сейчас). Спокойно объявите QVector<char>, потом сделайте resize - гораздо удобнее Только что написал, интерфейс использует массив char bufBig[1024 * 200] для скачки web-страницы полностью. Она 200К и парсим ее. Уйти на другой тип ? А смысл ?!! Все равно где хранить. Пока скачиваю ее полностью в этот массив. Название: Re: Строки в стеке или в куче ? Отправлено: Sahab от Март 09, 2011, 11:21 а если страничка больше указанного размера?
Название: Re: Строки в стеке или в куче ? Отправлено: Igors от Март 09, 2011, 11:35 Только что написал, интерфейс использует массив char bufBig[1024 * 200] Ну и делайте то же самое но через вектор, который прекрасно приводится к C массиву. А потом дойдут руки до того как узнать размер страницы - и у Вас все уже готово/на руках. А то char bufBig[1024 * 200] напоминает злобного носорога с плохим зрением :)для скачки web-страницы полностью. Она 200К и парсим ее. Уйти на другой тип ? А смысл ?!! Все равно где хранить. Пока скачиваю ее полностью в этот массив. Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 09, 2011, 12:11 а если страничка больше указанного размера? Почему больше ? 120-140К Как раз все влазит. Ну и делайте то же самое но через вектор, который прекрасно приводится к C массиву. А потом дойдут руки до того как узнать размер страницы - и у Вас все уже готово/на руках. А то char bufBig[1024 * 200] напоминает злобного носорога с плохим зрением :) Размер HTML-страницы я уже знаю из заголовка. А чем лучше для хранения тип QVector<char> по сравнению с массивом char. Тем, что я сразу жестко отвел 200К (уже в куче). Так может динамически его выделять просто. Размер массива будет выделен в зависимости от размера в заголовке. Все одно хранить, потом парсить ! Название: Re: Строки в стеке или в куче ? Отправлено: twp от Март 09, 2011, 13:06 А чем лучше для хранения тип QVector<char> по сравнению с массивом char. Захаркодить размер массива в программе? Хм, довольно сомнительный аргумент. Такое решение может быть хорошим только для лаборатороки или теста. Оптимальным решением было бы изначально хранить все в QString, но я не уверен возможно ли это сделать в данном контексте.Тем, что я сразу жестко отвел 200К (уже в куче). Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 09, 2011, 13:14 Захаркодить размер массива в программе? Хм, довольно сомнительный аргумент. Такое решение может быть хорошим только для лаборатороки или теста. Предлагаете динамически выделить в зависимости от размера web-страницы ? Igors уже предлагал QVector<char>, только вот смысла пока не пойму. И так и так массив в памяти выделять. Оптимальным решением было бы изначально хранить все в QString, но я не уверен возможно ли это сделать в данном контексте. Так данные же скачиваются постепенно (web-страница) и складываются в массив char. Хех ! Вот и решение, убивающее 2-х зайцев: отказаться от большого массива, складывать сразу все в QString через маленький буффер (1024 байта). Название: Re: Строки в стеке или в куче ? Отправлено: brankovic от Март 09, 2011, 13:21 А чем лучше для хранения тип QVector<char> по сравнению с массивом char. Вектор просто удобный и безопасный интерфейс к оператору new. Можно написать так: Код
а можно так: Код
и даже так: Код
Вариант 1 самый громоздкий, плюс надо предусмотреть возможность вылета исключения, не проскочить delete и т.д. Вариант 3 самый быстрый, но неудобный, ненадёжный и нестандартный. А вариант 2 самый простой. Им пользоваться лучше всего, потому что легче всего. Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 09, 2011, 13:43 Эээ, наверное забыл написать, что данные приходят в малый буффер (char buff[1024]).
А потому: Цитировать Отказываемя от большого массива, складываем сразу все в QString из маленького буффера (1024 байта). Только как лучше: 1) Повторно перераспределять память: Код
2) Более гибко управлять памятью без перераспределения : Код
Это набросок просто. QString нужен, поскольку web-страница в кодировке UTF-8. Название: Re: Строки в стеке или в куче ? Отправлено: brankovic от Март 09, 2011, 13:57 Только как лучше: 1) Повторно перераспределять память: Код
2) Более гибко управлять памятью без перераспределения : лучше 1, поскольку 2 ничего особо не даст (ну может копейки какие) ((интересно, это сработает, если utf8 символ разрежет границей буфера?)) Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 09, 2011, 14:36 интересно, это сработает, если utf8 символ разрежет границей буфера?)) Вроде пашет. Русские символы пишет. Хотя нужен всего title. ;D Да, решил вроде узкое место ! Название: Re: Строки в стеке или в куче ? Отправлено: twp от Март 09, 2011, 14:42 а мне больше по душе вариант без распределения, только можно сделать проще, как в примере из асистента:
Код: result.reserve(maxSize); Цитировать интересно, это сработает, если utf8 символ разрежет границей буфера? скорее всего будут проблемыНазвание: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 09, 2011, 14:53 а мне больше по душе вариант без распределения. Да, правильнее. Цитировать скорее всего будут проблемы Вроде 1024 успешно делится на 2 ?!! Что предлагаете ? Название: Re: Строки в стеке или в куче ? Отправлено: twp от Март 09, 2011, 15:38 делится то оно делится, просто UTF-8 символ может иметь размер от 1 до 4 байт и чтоб программа корректно работала с любым языком все-таки наверно придется накапливать данные как было предложено раннее в QVector<char> или QByteArray, а затем конвертануть (а не просто приравнять) в QString через
Код: QString QString::fromUtf8 ( const char * str, int size = -1 ) [static] Название: Re: Строки в стеке или в куче ? Отправлено: fuCtor от Март 09, 2011, 17:59 Просто как вариант: если страница является валидным XML (тобишь XHTML), то можно попробовать использовать для парсинга данных http://doc.qt.nokia.com/4.7/qxmlstreamreader.html.
Название: Re: Строки в стеке или в куче ? Отправлено: Igors от Март 10, 2011, 11:34 Код
По теме: связываться с QString, на мой взгляд, здесь не следует - он предназначен для строк и будет париться с кодировкой. Просто вектор, тем более что размер загружаемых данных известен Код
Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 11:42 вектор чаров О_о а QByteArray чем не угодил??
Название: Re: Строки в стеке или в куче ? Отправлено: brankovic от Март 10, 2011, 11:53 Прекрасная, удобная конструкция - но увы, эта радость только на gcc, на Вындоуз "так нельзя" :'( Оковы тяжкие падут, Темницы рухнут — и свобода (в лице mingw) Вас примет радостно у входа, Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 11:57 ...и сгенерит веселый код
типа такого: Код: CPU Disasm Код: CPU Disasm Название: Re: Строки в стеке или в куче ? Отправлено: kkk777kkk от Март 10, 2011, 12:07 а не могли бы вы обьяснить ассемблерный код? в чем там минус?
Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 12:21 псевдокод:
Код: buf = a; 2й код ваще ноукомментс Код: goto label; Название: Re: Строки в стеке или в куче ? Отправлено: kkk777kkk от Март 10, 2011, 12:52 обидно за любимый компиль :)
но его же тоже люди писали :) Название: Re: Строки в стеке или в куче ? Отправлено: brankovic от Март 10, 2011, 13:01 обидно за любимый компиль :) но его же тоже люди писали :) Нет ни флагов компиляции, ни версии, ничего.. явная провокация ;) Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 13:06 версия с к-ая шла с qt 4.7.0 кажется. Флаги деолтные при компиляции qt прогаммы. Не говорите мне про -O делать оптимизации за счет изначально кривого кода - это пять...
Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 10, 2011, 13:29 Сделал через маленький буффер и байтовый массив.
Сетевой класс был сделан на WinSock2 (че фу сразу !). Коротко: Код
Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 10, 2011, 13:34 Код: char buf [size]; Это для вектора касается или "нельзя" для Win ? Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 13:37 это по стандарту си/с++ нельзя, страшную тайну открою. ну гцц чхать на стандарты)) в msvc нельзя так писать
Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 10, 2011, 13:43 А как раньше данные в буффер принимали ?
Код
И так нельзя ? А как тогда нужно ??? Кошмариус ! ;D Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 13:45 переменную нельзя:) константу можно естессно. Типа должно быть известно на этапе компиляции сколько стека срезать.
причем кажется хак вида Код: const int i = func(); в мсвц работать таки будет, но я не уверен, давно это тестил. Название: Re: Строки в стеке или в куче ? Отправлено: twp от Март 10, 2011, 13:56 для i мало const, она должна быть определена на этапе компиляции
Название: Re: Строки в стеке или в куче ? Отправлено: Etud от Март 10, 2011, 13:57 переменную нельзя:) константу можно естессно. А разговор про переменную ?!! Тут уже мозг замылился. По сабжу: С байтовым массивом получилось все компактно, и когда получил нужные параметры перекодировал заголовок. Гораздо лучше чем было. Спасибо всем ! Хотя может рано закрывать... Название: Re: Строки в стеке или в куче ? Отправлено: brankovic от Март 10, 2011, 14:04 Не говорите мне про -O делать оптимизации за счет изначально кривого кода - это пять... как дети, в самом деле. Задание компилятору: надо сгенерить код, оптимизировать не надо, но чтобы хоть чуть-чуть причесать, а то Авварон будет недоволен.. Код: const int i = func(); такое же нарушения стандарта. 2Etud: можно объявлять массив, если в скобках выражение известное на этапе компиляции, например 1024 или 10 * sizeof (int) и т.п. Название: Re: Строки в стеке или в куче ? Отправлено: BRE от Март 10, 2011, 14:14 это по стандарту си/с++ нельзя, страшную тайну открою. ну гцц чхать на стандарты)) в msvc нельзя так писать Авварон, ты серьезно про это? ::)Насчет gcc... возможность указать переменный размер массива - это расширение gcc, которое войдет в следующий стандарт! Если не хочешь использовать расширения - запрети их (есть специальный ключ). Как можно писать в одном предложении слова "msvc" и "стандарт"? ;) Название: Re: Строки в стеке или в куче ? Отправлено: Пантер от Март 10, 2011, 14:18 Да, ЕМНИП, msvc далек от стандарта. В принципе, как и все некрософтофское.
Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 14:39 ах, ну извините
Цитировать Major changes in the second edition included: таки сделали в каком-то из стандартов. Ну хорошо.- variable length arrays Название: Re: Строки в стеке или в куче ? Отправлено: Igors от Март 10, 2011, 16:52 Как можно писать в одном предложении слова "msvc" и "стандарт"? ;) Ну конечно, легко рассуждать сидя на "экологически чистой" Федоре (правильно?)А что я скажу людям работающим над проектом вместе со мной? Цитировать Пацаны, значит так: мелкософт кал. Поэтому собирайте манатки, переходим на др. компилятор! Так мне могут вежливо ответить типаЦитировать Слушай, Игорь, у меня там static либов с десяток, перекомпили если ты такой резвый - а потом уж обсудим Название: Re: Строки в стеке или в куче ? Отправлено: Авварон от Март 10, 2011, 17:04 ну хз, писал себе на мсвц и кроме пресловутого бага с не компиляцией массива на стеке (к-ый таки да, потенциальный краш) у меня с ним проблем не было. Наоборот он более педантичный что ли) (--pedantic-_-) Заставляет править вещи типа забытых ретурнов.
То ли я стандарт с++ не знаю, то ли мсвц его таки соблюдает в достаточной мере. Вот когда там темплейтов нормальных не было, тогда да)) Название: Re: Строки в стеке или в куче ? Отправлено: Igors от Март 10, 2011, 17:16 ну хз, писал себе на мсвц и кроме пресловутого бага с не компиляцией массива на стеке (к-ый таки да, потенциальный краш) у меня с ним проблем не было. Наоборот он более педантичный что ли) (--pedantic-_-) Заставляет править вещи типа забытых ретурнов. MSVC молотит много варнингов - но в основном "не по делу". Ну да, я присваиваю float значение double, ладно, нарушаю и за это отвечу. Но вот чего он (гад) не показывает что переменная не инициализирована до ее использования (реально ценный варнинг). У gcc (даже старые версии) здесь все четко.То ли я стандарт с++ не знаю, то ли мсвц его таки соблюдает в достаточной мере. Вот когда там темплейтов нормальных не было, тогда да)) Название: Re: Строки в стеке или в куче ? Отправлено: BRE от Март 10, 2011, 19:41 Ну конечно, легко рассуждать сидя на "экологически чистой" Федоре (правильно?) На Федоре, а точнее на продуктах redhat, просидел лет 10. Всем нравилось, но утомляла необходимость полного апгрейда с выходом новой версии. Сейчас, уже несколько месяцев, сижу на arch - проблем не знаю. :)А что я скажу людям работающим над проектом вместе со мной? Это можно говорить всем людям работающими над проектом вместе с тобой. ;) Название: Re: Строки в стеке или в куче ? Отправлено: Fat-Zer от Март 11, 2011, 01:58 по поводу массивов переменной длинны:
В си они уже в стандарте (С99), а вот когда добрая корпорация мелкомягких соблаговолит его поддерживать - не известно. Судя по всему они по этому поводу даже не чешутся... |