LINUX.ORG.RU

[C] Как правильно работать с буферами неизвестного конечного размера.

 


0

1

Допустим у нас есть приложение которое соединяется с базой данных и выгребает оттуда нужную информацию по запросу. Эту информацию она должна уложить в буфер char *. Потом от этого буфера берутся отпечатки. Как правильно реалоцировать память в таких случаях.

Алгоритм действия примерно такой:

1. Запросили запрос и получили хэндл на результат.

2. В цикле перебираем полученные записи и добавляем их в буффер

3. Дальнейшая обработка буфера.

★★★

Последнее исправление: visual (всего исправлений: 1)

Я не понял, чего ты хотел сказать своим алгоритмом.

А с помощью клиентских библиотек как MySQL, так и PGSQL можно узнать длины полей в принятой строке, если что

yoghurt ★★★★★
()
Ответ на: комментарий от yoghurt

я про то, что я не хочу делать realloc на буффер при добавлении новой ячейки. длины полей - это хорошо. Но если записей много, не нажрётся ли моя прога памяти при реаллоках?

visual ★★★
() автор топика

наверняка тебе подойдет что-то вроде GString

anonymous
()
Ответ на: комментарий от visual

а зачем тебе делать реаллоки? и чему ты собрался делать реаллок? построчно не можешь чтоли данные обрабатывать приходящие?

З.Ы. Когда в этом треде я говорю «построчно», я имею ввиду не текстовые строки, а строки из выборки БД

yoghurt ★★★★★
()
Ответ на: комментарий от visual

Но если записей много, не нажрётся ли моя прога памяти при реаллоках?

не знаю как в GString, а в C++ размер буфера увеличивается постоянно вдвое, так что «наесться» реаллоками не получится

anonymous
()

Если речь идет о сетевом доступе к базе данных, ты в потерю производительности на realloc точно не упрешься. Можно сделать умное увеличение размера буфера с учетом скорости получения данных, но хватит и тупого прироста на фиксированное значение при достижении границы.

note173 ★★★★★
()

А зачем делать realloc? Просто создаем структуру - связанный список, при добавлении записи выделяем память для нее и указатель next предыдущей записи указываем на текущий.

А вообще, если, например, sqlite'ом пользоваться, то он возвращает количество результирующих буферов - так что сразу можно сделать malloc для массива указателей, а потом уже отдельно делать alloc'и для каждой очередной записи и модифицировать соответствующим образом очередной указатель из массива.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

А вообще, если, например, sqlite'ом пользоваться, то он возвращает количество результирующих буферов

и с каких это пор SQLite научился отдавать кол-во записей в курсоре?

anonymous
()
Ответ на: комментарий от Eddy_Em

ну как минимум у меня есть 2 варианта - твой или realloc.

Ушёл реализовывать.

visual ★★★
() автор топика
Ответ на: комментарий от Eddy_Em

Параметр argc в sqlite3_exec

«The 2nd argument to the sqlite3_exec() callback function is the number of columns in the result.», что не есть кол-во записей, и, что опять показывает твое незнание, для получения размера данных в каждом поле для текущей записи - есть отдельная функция в sqlite, так что можно не маяться с массивом указателей, а просто выделить буфер и последовательно в него все скопировать

aho__
()
Ответ на: комментарий от anonymous

чем GString не угодил?

Нафиг всякую дрянь использовать?

или свой велосипед все лучше чем realloc'ами махать по всей программе

Конечно.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от aho__

Да мне особо разбираться лень было: работает - а и ладно :)

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

Кстати, тебя же вроде как того белку... Нет?

без понятия, это не мне решать, что делать - продолжать меня банить или оставить в покое

aho__
()
Ответ на: комментарий от Eddy_Em

учитесь аргументировать свои умозаключения чем по вашему дрянь GString ? мне так вот наоборот кажется если в программе налево ир направо махают ealloc'ами а GString (или свой велосипед) не используют то это печально

anonymous
()
Ответ на: комментарий от Eddy_Em

А вариант с созданием буфера с большИм запасом не рассматривался?

То есть тогда realloc будет не на каждый чих, а только в тех случаях, когда буфера не хватает. А если повезёт, то и ни одного realloc'а не будет.

OldFatMan
()
Ответ на: комментарий от anonymous

Если не забывать подчищать память, то alloc'и вполне даже могут быть лучше всяких GString (т.к. последнее - унифицировано и вполне может содержать уйму ненужной информации, а мы своим «кастрированным» велосипедным GString'ом выделяем именно столько памяти, сколько нужно).

А использовать glib, по-моему, вообще неразумно.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

P.S. Я ни разу не программист, так что мое мнение монужно вообще не принимать к сведению.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от OldFatMan

А вариант с созданием буфера с большИм запасом не рассматривался?

Для реализации чтения POST-запроса (по ссылочке этого нет, т.к. руки не доходят добить), чтобы побайтно не читать.

Только после обработки нужно будет сделать strdup и освободить первоначально выделенную с избытком память. Если выделять мегабайт по 30, вполне возможно, что realloc никогда вызывать и не придется.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

А использовать glib, по-моему, вообще неразумно.

если писать не только под линукс - да, будет морока с лишней библиотекой, но и то небольшая, в остальном - вполне себе стандартный набор инструментов, даже Qt на него завязана

aho__
()
Ответ на: комментарий от ae1234

да. Я уже сбился со счета, сколько лоровцев меня спросили о моей аватаре (%

grouzen ★★
()
Ответ на: комментарий от stack_protector

Ага, особенно в винде.

глупый комментарий, очевидно Qt завязана на системные библиотеки целевых ОС, на каждой ОС такой набор свой

// aho

anonymous
()
Ответ на: комментарий от Eddy_Em

Очевидно, glib не является системной библиотекой

ты еще скажи, что у тебя ее в системе нет, или ты ее легко сможешь удалить

так что нечего это УГ приводить в пример.

ваши личные комплексы на нужность и качество библиотек не влияют, ваш К.О.

anonymous
()
Ответ на: комментарий от stack_protector

glib опционален

но включен по дефолту, вряд ли есть дистрибутив, где Qt собран без него

anonymous
()
Ответ на: комментарий от anonymous

ты еще скажи, что у тебя ее в системе нет, или ты ее легко сможешь удалить

Она у меня есть, но только из-за того, что всякие GTK на нее завязаны.

Eddy_Em ☆☆☆☆☆
()
Ответ на: комментарий от Eddy_Em

если с Qt сравнивать

Qt не аналог Glib. Qt аналог GLib + Gtk + GObject. Сам по себе GLib не содержит не системы типов, ни ООП, ни графическо функций.

stack_protector
()
Ответ на: комментарий от Eddy_Em

Она у меня есть, но только из-за того, что всякие GTK на нее завязаны.

если попробуешь удалить - «улетят» далеко не только gtk и программы на нем

anonymous
()
Ответ на: комментарий от stack_protector

Но слово «завязан» все равно неуместно.

как раз уместно, вот слово «необходим» - да, уже неуместно

anonymous
()

Как правильно реалоцировать память в таких случаях.

В garray, например, realloc делается в сторону ближайшей степени двойки, т.е. довольно редко.

quasimoto ★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.