Russian Qt Forum
Октябрь 01, 2024, 02:41 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Строки в стеке или в куче ?  (Прочитано 26225 раз)
Etud
Гость
« : Март 08, 2011, 12:53 »

В классе My имеются символьные массивы в стеке.
Далее символьная строка (тип char) присваивается QString.

Код
C++ (Qt)
char buffer[2048];
char bufLoad[1024];
char bufBig[1024 * 200];
 
QString str = QString(*buffer);
 

Как известно, существует опасность падения программы
(на 20-й раз, 30-й, ...), поскольку строки большие  > 200 КБ, пару строк и достигли 1MБ (предел для стека).
Рекомендуют больше 1 КБ в стек не ложить.

Решил в классе My выделить память в куче
(т.е. создать динамические массивы).

Код
C++ (Qt)
char *s;
s = new char[1024 * 200];
 

Уже лучше и риск меньше !

Вопросы:
1) Строка (тип QString) увеличивает память в стеке ?
2) Под эту строку тоже отводится 200K, есть ли тут риск ?
Записан
Kolobok
Гость
« Ответ #1 : Март 08, 2011, 13:15 »

Если объект My создан в куче, то какая разница?!
Записан
Etud
Гость
« Ответ #2 : Март 08, 2011, 13:34 »

Да, объект my класса Му создан в куче.

Не подумал про сам объект.

То есть эти массивы будут в куче, переводить их в динамику не надо ?
Записан
Stiff
Гость
« Ответ #3 : Март 08, 2011, 13:48 »

Код
C++ (Qt)
char buffer[2048];
char bufLoad[1024];
char bufBig[1024 * 200];
 
QString str = QString(*buffer);
 
Про последнюю строку: так писать некорректно. Во-первых, тип переменной buffer это char *, то есть указатель на символ, не нужно его разыменовывать, у QString нет конструктора с единственным аргументом типа char, но есть с типом char *.
Правильнее написать так:
Код
C++ (Qt)
QString str(buffer);
Во-вторых, указатель на массив, передаваемый конструктору QString обязательно должен заканчиваться нулём, иначе возможно выхождение за пределы массива! Дабы перестраховаться, присвой последним значениям массивов нули:
Код
C++ (Qt)
buffer[2047] = '\0'
Переполнение стека не при чём, ищите ошибки.
« Последнее редактирование: Март 08, 2011, 14:02 от Stiff » Записан
Etud
Гость
« Ответ #4 : Март 08, 2011, 15:08 »

Тут был псевдокод. Это отработано.

Вопрос про память, чтобы краха не было.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Март 08, 2011, 16:38 »

Вопросы:
1) Строка (тип QString) увеличивает память в стеке ?
2) Под эту строку тоже отводится 200K, есть ли тут риск ?
1) Нет (точнее на 4/8 байт независимо от размера строки)
2) Есть если Вы (нагловато) размещаете такие данные на стеке. Практичнее использовать QVector <char> (или std::vector)
3) QString сожрет вдвое больше памяти (2 байта на символ в unicode)
Записан
Etud
Гость
« Ответ #6 : Март 08, 2011, 19:48 »

Спасибо, Igors за ответ.

Конечно, QString занимает памяти вдвое больше по сравнению со строкой char-ов.

Еще раз уточню задачу:

Есть класс My, который имеет строку
Код
C++ (Qt)
char bufBig[1024 * 200];

Эту строку я переводил в строку QString, чтобы произвести в ней поиск (парсинг),
что несомненно удобно из-за функций поиска подстрок.

Слабое место у меня это массив  bufBig, потому что 200К памяти отведено + еще строка QString (400К ?).

Получается, что поиск (парсинг) лучше делать в массиве bufBig, что не удобно, так так надо писать свою функцию поиска.
С QString это было очень удобно !


Вопросы:
1) При создании объекта my класса My в куче  массив bufBig оставить без изменений (в стеке) или лучше тоже в куче ?
2) Строка
Код
C++ (Qt)
QString str = QString(buffer);
при создании объекта my в куче размещается в стеке ?

Извините, что много спрашиваю, но все 1-й раз.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #7 : Март 08, 2011, 20:06 »

Есть класс My, который имеет строку
Код
C++ (Qt)
char bufBig[1024 * 200];
От этого надо (срочно) избавиться. Такое "жирное" описание никак не гуд, т.к. оно заставляет компилятор выделять стек-память впустую и без всякой необходимости. Все что "выше травы" должно быть в куче. Обычно это не вызывает затруднений., если Ваш случай особый - сообщите детали, обсудим
Записан
brankovic
Гость
« Ответ #8 : Март 08, 2011, 20:10 »

В классе My имеются символьные массивы в стеке.
Код
C++ (Qt)
char buffer[2048];
char bufLoad[1024];
char bufBig[1024 * 200];
 

Так они в классе или в стеке? Если объявлены как член класса, то они там, где соотв. экземпляр:

Код
C++ (Qt)
struct My
{
  char buf [123];
};
 
void some_function ()
{
 My m;
 My *p = new My;
}
 

объект m и его поле buf будут в стеке, объект по адресу p и его поле buf будут в куче. Или имеется в виду другая конструкция?

Как известно, существует опасность падения программы
(на 20-й раз, 30-й, ...), поскольку строки большие  > 200 КБ, пару строк и достигли 1MБ (предел для стека).
Рекомендуют больше 1 КБ в стек не ложить.

просто интересно, откуда данные? Я знаю, что бывают такие падения, но чтобы 1 мегабайт  всего, как-то не верится.

Вопросы:
1) При создании объекта my класса My в куче  массив bufBig оставить без изменений (в стеке) или лучше тоже в куче ?
2) Строка
Код
C++ (Qt)
QString str = QString(buffer);
при создании объекта my в куче размещается в стеке ?

строка неявно использует буфер, который выделяется в куче. Собственно все контейнеры так устроены, если даже сам контейнер в стеке, то там хранится только указатель на буфер в куче.

Не знаю, какие у вас требования по памяти, но я бы не заморачивался на счёт размера QString. В большинстве случаев ни память ни скорость для строк не критичны, а читаемость и компактность кода важны всегда.
Записан
Stiff
Гость
« Ответ #9 : Март 08, 2011, 20:37 »

Получается, что поиск (парсинг) лучше делать в массиве bufBig, что не удобно, так так надо писать свою функцию поиска.
С QString это было очень удобно !
Делай парсинг в QByteArray, функции с QString идентичные
Записан
Etud
Гость
« Ответ #10 : Март 08, 2011, 21:24 »

Так они в классе или в стеке?

Переменная-член bufBig принадлежит классу My:
Код
C++ (Qt)
class My
{
 char bufBig[1024 * 200];
};
 

Объект создается в куче:
My *p = new My;

Спасибо, значит все тут в куче.  Просвятили !

Значит, если будет даже 10 объектов, память выделяется в куче,
размер окна большой - ее должно хватить ?

Цитата: brankovic
просто интересно, откуда данные? Я знаю, что бывают такие падения, но чтобы 1 мегабайт  всего, как-то не верится.

Из форумов...Или не верно ?

Цитата: brankovic
строка неявно использует буфер, который выделяется в куче. Собственно все контейнеры так устроены, если даже сам контейнер в стеке, то там хранится только указатель на буфер в куче.

В моем случае строка str используется в другом классе Tu (он в куче)
Код
C++ (Qt)
QString str = QString(buffer);
и получает указатель на мой большой массив-буффер из класса My.


Цитата: brankovic
Не знаю, какие у вас требования по памяти, но я бы не заморачивался на счёт размера QString. В большинстве случаев ни память ни скорость для строк не критичны, а читаемость и компактность кода важны всегда.

Да нет требований, главное чтобы пахала. Начитался флейма, а знаний про память мало.

Вот и я заметил, что удобство интерфейса и поддержка кода - это много.
« Последнее редактирование: Март 08, 2011, 21:41 от Etud » Записан
brankovic
Гость
« Ответ #11 : Март 08, 2011, 22:09 »

Значит, если будет даже 10 объектов, память выделяется в куче,
размер окна большой - ее должно хватить ?

число объектов * размер объекта = потребление памяти. Достаточно оценить эти величины. На символ можно считать 2 байта, если кустринг.

Цитата: brankovic
просто интересно, откуда данные? Я знаю, что бывают такие падения, но чтобы 1 мегабайт  всего, как-то не верится.
Из форумов...Или не верно ?

от платформы зависит, наверное. Линукс, например, по умолчанию выделяет 10 мегабайт на стек, а потом он может ещё расти. Бывают падения, если выделять очень большие куски в стеке (100 мегабайт). Толком не знаю, как там устроено. Спрашивал, потому что думал может почитать что-то есть.

В моем случае строка str используется в другом классе Tu (он в куче)
Код
C++ (Qt)
QString str = QString(buffer);

в этом коде QString сначала посчитает размер buffer (найдёт первый '\0'), потом выделит в куче буфер такого же размера, потом скопирует всё туда. И забудет про buffer навсегда.

Вообще пользоваться массивами в C-стиле нужно только ради оптимизации, и только когда точно знаешь, что делаешь. Сам всегда использую контейнеры, пока тормозить не начнёт, и обычно не начинает.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Март 09, 2011, 10:44 »

Код
C++ (Qt)
class My
{
 char bufBig[1024 * 200];
};
 

Объект создается в куче:
My *p = new My;
Нехорошо, Вас никто не заставляет распределять память немедленно и жестко (как сейчас). Спокойно объявите QVector<char>, потом сделайте resize - гораздо удобнее
Записан
Etud
Гость
« Ответ #13 : Март 09, 2011, 10:51 »

Цитата: brankovic
Вообще пользоваться массивами в C-стиле нужно только ради оптимизации, и только когда точно знаешь, что делаешь.

Класс My это обертка вокруг С-шных функций, потому сразу не использовал QString (нельзя так).

Есть класс My, который имеет строку
Код
C++ (Qt)
char bufBig[1024 * 200];
От этого надо (срочно) избавиться. Обычно это не вызывает затруднений., если Ваш случай особый - сообщите детали, обсудим.

Этот буффер нужен для парсинга HTML-страницы. Оттуда дастается заголовок и другие параметры.

Потому скачиваю ее полностью, дальше парсим.

И вот тут уже важен алгоритм. Как можно получить эти части (нужные параметры).
На лету парсить при скачке непросто.


 
« Последнее редактирование: Март 09, 2011, 11:00 от Etud » Записан
Etud
Гость
« Ответ #14 : Март 09, 2011, 10:57 »

Нехорошо, Вас никто не заставляет распределять память немедленно и жестко (как сейчас). Спокойно объявите QVector<char>, потом сделайте resize - гораздо удобнее

Только что написал, интерфейс использует массив char bufBig[1024 * 200]
для скачки web-страницы полностью. Она 200К и парсим ее.

Уйти на другой тип ? А смысл ?!! Все равно где хранить.

Пока скачиваю ее полностью в этот массив.
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.966 секунд. Запросов: 23.