Страниц: 1 [2] 3
  Печать  
Автор Тема: Массив строк и PtListAddItems  (Прочитано 19623 раз)
qnxloder
Sr. Member
****
Offline Offline

Сообщений: 292


Просмотр профиля
« Ответ #15 : Марта 02, 2011, 11:13:39 am »

To Hed: на самом деле data указатель на структуру, которая переводится в строку посредством sprintf Smiley
Записан
Hed
Jr. Member
**
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #16 : Марта 02, 2011, 11:20:42 am »

To Hed: на самом деле data указатель на структуру, которая переводится в строку посредством sprintf Smiley

В корне не верный подход. Какова вероятность того, что '\0' встретиться в середине структуры? Какова вероятность того, что '\0' всегда будет в конце структуры? Прибавте к этому еще управляющие символы.
В этом случае лучшем контролем будет переход к строке поэлементно.

Но если, по вашим утверждениям, ваш вариант работоспособен, то *data можно смело рассматривать как указатель на строку.
« Последнее редактирование: Марта 02, 2011, 11:40:48 am от Hed » Записан
qnxloder
Sr. Member
****
Offline Offline

Сообщений: 292


Просмотр профиля
« Ответ #17 : Марта 02, 2011, 12:26:46 pm »

Так понятно? Smiley

struct tm reg_start_tm, reg_end_tm;

localtime_r(&reg_range_cdg->start_sec, &reg_start_tm);
localtime_r(&reg_range_cdg->end_sec, &reg_end_tm);

sprintf(cdg_str, "%d\t%02d/%02d/%02d %02d:%02d:%02d\t%02d/%02d/%02d %02d:%02d:%02d\n",
reg_range_cdg->num,
            reg_start_tm.tm_mday, reg_start_tm.tm_mon+1, reg_start_tm.tm_year + 1900,
               reg_start_tm.tm_hour, reg_start_tm.tm_min, reg_start_tm.tm_sec,
            reg_end_tm.tm_mday, reg_end_tm.tm_mon+1, reg_end_tm.tm_year + 1900,
               reg_end_tm.tm_hour, reg_end_tm.tm_min, reg_end_tm.tm_sec);

не хотел захламлять ветку, поэтому сократил пример.
« Последнее редактирование: Марта 02, 2011, 12:28:27 pm от qnxloder » Записан
Hed
Jr. Member
**
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #18 : Марта 02, 2011, 02:25:48 pm »

Так понятно? Smiley

struct tm reg_start_tm, reg_end_tm;

localtime_r(&reg_range_cdg->start_sec, &reg_start_tm);
localtime_r(&reg_range_cdg->end_sec, &reg_end_tm);

sprintf(cdg_str, "%d\t%02d/%02d/%02d %02d:%02d:%02d\t%02d/%02d/%02d %02d:%02d:%02d\n",
reg_range_cdg->num,
            reg_start_tm.tm_mday, reg_start_tm.tm_mon+1, reg_start_tm.tm_year + 1900,
               reg_start_tm.tm_hour, reg_start_tm.tm_min, reg_start_tm.tm_sec,
            reg_end_tm.tm_mday, reg_end_tm.tm_mon+1, reg_end_tm.tm_year + 1900,
               reg_end_tm.tm_hour, reg_end_tm.tm_min, reg_end_tm.tm_sec);

не хотел захламлять ветку, поэтому сократил пример.


вопросов больше нет  Wink
Записан
GrayCat
Full Member
***
Offline Offline

Сообщений: 121


Gray©at


Просмотр профиля
« Ответ #19 : Марта 03, 2011, 12:33:12 am »

Я и не утверждал, что знаю, как работает PtList. Просто я когда-то столкнулся именно с тем, что со строками в стеке оно не работало, выкручивался malloc-ом. Возможно, это было во времена QNX6.2.0, а теперь исправили...
Записан

Gray©at
lastcross
Full Member
***
Offline Offline

Сообщений: 224


Просмотр профиля
« Ответ #20 : Марта 07, 2011, 05:38:35 pm »

Может немного офтом, но...
Давно ничего не разрабатовал под QNX, но не уж-то для работы с виджетами нельзя использовать в проекте C++?
Если можно, то к чему все эти танцы с явным выделением памяти под строки, если можно заюзать std::string?
По поводу sprintf(и др.) - буквально неделю назад, в проекте (проект клиентского кода)  который достался в наследство, правил "забавный" кусок кода из-за которого падали все клиенты приконекченные к серверу.
Причина простая - сервер присылал информации больше(по значениям) чем "кто-то" в клиенте выделял память под строковой буффер (для таких функций как sprintf, itoa...). Так как подобная инфа сервером отсылалась бродкастом - то крашились все клиенты синхронно.
Опять же вопрос, если таки C++ - то почему не std::stringstream вместо sprintf ?

Записан
oder
Гость
« Ответ #21 : Марта 07, 2011, 08:07:16 pm »

Может немного офтом, но...
Давно ничего не разрабатовал под QNX, но не уж-то для работы с виджетами нельзя использовать в проекте C++?

Опять же вопрос, если таки C++ - то почему не std::stringstream вместо sprintf ?

string - хороший класс. Но, если можно легко и безопасно обойтись без него в буфере на стёке, - лучше обойтись без него в буфере на стёке.
Записан
lastcross
Full Member
***
Offline Offline

Сообщений: 224


Просмотр профиля
« Ответ #22 : Марта 07, 2011, 08:54:18 pm »

Хм, класс хороший, но никто тут им не пользуется? Smiley
Я не вижу особого профита в использовании массива чаров по сравнению с контейнерами (темболее в данном контексте, да и с работой в GUI). Наоборот, мне показалось что именно там (при использовании) пытаются проводить какие-то операции со строками. А со стековыми массивами - получаем вероятность либо выйти за границы, либо сожрать лишнее место под стек. Эту "безопасность" Вы имели ввиду?
Если уж имеется ввиду ограничения на размер/использование кучи либо же что скорость "работы" с такой памятью меньше чем со стековой - то как по мне, это весьма преждевременная оптимизация (экономия на спичках)

В общем строки - это не тот пример, где легко и безопасно работать со стековым массивом. Один из примеров "небезопасности" я уже приводил
Записан
oder
Гость
« Ответ #23 : Марта 07, 2011, 09:06:05 pm »

Я не вижу особого профита в использовании массива чаров по сравнению с контейнерами (темболее в данном контексте, да и с работой в GUI). Наоборот, мне показалось что именно там (при использовании) пытаются проводить какие-то операции со строками. А со стековыми массивами - получаем вероятность либо выйти за границы, либо сожрать лишнее место под стек. Эту "безопасность" Вы имели ввиду?

Я имел ввиду то, что я сказал и ничего другого. Если, грубо говоря, надо отформатировать в текстовом представлении один int, передать его, как const char * и забыть о нём, - выглядит достаточно глупым выделять под него память на куче, передавать c_str() и тут же эту память освобождать.
Копейка рубль бережет.
Записан
oder
Гость
« Ответ #24 : Марта 07, 2011, 09:11:11 pm »

Также, если надо отформатировать дату в строку фиксированной длины (потому, что формат принудительно генерирует по два символа для всех чисел), - выглядит глупо восемь раз выделять и перевыделять буфер стринга, клея к нему куски, если можно один раз отформатировать всё через sprintf и один раз создать из буфера стринг.
« Последнее редактирование: Марта 07, 2011, 09:12:50 pm от oder » Записан
lastcross
Full Member
***
Offline Offline

Сообщений: 224


Просмотр профиля
« Ответ #25 : Марта 07, 2011, 10:42:08 pm »

Цитировать
Если, грубо говоря, надо отформатировать в текстовом представлении один int, передать его, как const char * и забыть о нём, - выглядит достаточно глупым выделять под него память на куче, передавать c_str() и тут же эту память освобождать.
Копейка рубль бережет

Как по мне, как раз обратное делать глупо:
1) Работаем с GUI - наши издержки с памятью ничто по сравнению с его издержками. Если в этом месте настолько важны наши издержки - то скорее всего придется изменять дизайн (например не перфрейм вызывать а потаймингу)

2) По поводу забыть - делаем шаблонный метод (а можно и конкретизированный по типу в названии аля IntToStr) например:
 
Код:
PtListAddItems(ABW_sel_reg_lst, ToStr(IntValue).c_str(), 1, 0);

и нет танцев с бубном непосредственно в коде по "надуманной оптимизации" с какими-то "строковыми" операциями (создание/удаление динамических массивов). Улучшается чтение кода. Разумеется и не обязательно возвращать в предложенном варианте по значению строку.

3) Расширяемость/поддержка/прозрачность кода - не дай Бог захотелось добавить Item с шаблонной строкой передаваемой в качестве параметра (формируемая из вне - некий префикс/суффикс в конечной строке). Интересно - будете тоже решать с помощью стека? И как? (п1 - работаем с GUI, экономим спички). Или в коде захотелось добавить через месяц еще пару тройку данных которые нужно перевести в строку (надеюсь все участники в проекте помнят что буфер тоже нужно расширить и при этом еще и посчитать на сколько).

4) Если специализировать метод ToStr с использованием std::stringstream - повысите безопасность (которую я наблюдал тут в примерах - выход за пределы статического массива) и забыв о головной боли при сборке в 32 или 64 битных или где int вообще 2 байта. Если уж совсем невтерпеж - специализируйте ToStr по быстродействию/памяти, но это делают уже перед релизом проекта

5) Про какое
Цитировать
восемь раз выделять и перевыделять буфер стринга
идет речь? И как вы это посчитали? std::stringstream может быть специализирован в конкретной stl-либе например точно так же как и вектор (в контексте переалокации памяти при добавлении элементов - выделять порциями).

6) В некоторых stl реализациях - std::string имеют разную форму хранения данных для длинных и коротких строк - что вы в этом случае оптимизируете?




Записан
oder
Гость
« Ответ #26 : Марта 08, 2011, 01:51:17 am »

Мне лень спорить.
Конечно, в некоторых случаях вы правы (особенно, если так написана вся программа и если это гуя). Но рассчитывать на то, что у вас будет умный STL, который за вас будет выделять память кусками тоже нельзя. STLи - они разные бывают: одни умные, другие - не очень. Не надо надеяться, что класс за вас всю работу сделает и вообще, это, зачастую, очень мешает, когда класс решает всё за программиста.
И я тоже прав, что если программа - не гуёвая и можно легко сэкономить несколько перевыделений памяти - грех их не сэкономить. На расширение буфера при добавлении параметров способы есть - надо дисциплину держать только. А оптимизация особенно пригодится, когда в один прекрасный день заказчик решает, что ему на одном не самом шустром компьютере нужно запустить как можно больше экземпляров вашей прграммы (штук 30-40, к примеру).
И тогда все ваши попущения вам скажутся! Любая халтура рано или поздно всегда вылазит боком!
Записан
oder
Гость
« Ответ #27 : Марта 08, 2011, 04:47:59 pm »

Короче, всё правильно вы, отроче, глаголите - не напрягайтесь по-напрасну. Я только говорил не юзать тупо стринг как временный буфер фиксированной длины и не клеить его тупо по кусочкам.
Записан
lastcross
Full Member
***
Offline Offline

Сообщений: 224


Просмотр профиля
« Ответ #28 : Марта 13, 2011, 01:32:47 am »

Вот, тема про строки, а вслед и про оптимизацию всплыла в соседней ветке (решил постить это тут, так как ответ к строкам ближе нежели про логи). Почти одновременно, тут вспомнился случай "оптимизации". Хочется спросить, а почему Вы Oder не порекомендовали в методе для передачи ГУЮ строки передавать не то чтобы просто char [], который в стеке, а еще более "оптимальный" вариант - статический массив Smiley ? Он ведь по выделению памяти может оказаться куда эффективнее Smiley

Так вот про случай - был такой "оптимизатор" , выделил в коде статический буффер (типа юзается часто, зачем же пере-создавать для каждого объекта). Сходу реализацию его никто не посмотрел (да и темболее - приватный мембер). Далее, изменяются требования в процессе проектирования, которые предлагают распараллелить некоторые вычисления (в том числе, где-то глубоко и код "оптимизатора"). Процесс поиска "черных кошек" можно не описывать.
Я к чему - разумеется, в ходе распараллеливания вроде бы обязаны были б просмотреть весь код на статические переменные до его использования. Но очевидно следующее:
1) Заоптимизировал заранее "нЕчто", неопределив профит от оптимизации.
2) Оптимизация на последнем этапе проекта - когда распараллеливание уже было бы внедренно, куда эффективнее может быть, чем на этапе когда неизвестно кто и как и в какой схеме код ваш пользовать будет.
Записан
oder
Гость
« Ответ #29 : Марта 13, 2011, 01:59:36 pm »

Мне пофигу ваш сарказм.
Вы говорите не об "оптимизаторе", а от "ламере", который программировать не умел. Не надо путать оптимизацию и обычную неграмотность.
Записан
Страниц: 1 [2] 3
  Печать  
 
Перейти в: