0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
||||||
1 | ||||||
Утечка памяти в функции24.10.2012, 04:38. Показов 5053. Ответов 28
Метки нет (Все метки)
Сама суть
Есть fcgi-приложение которое парсит полученные get-данные и потом производит выборку по MySQL. В приложении есть функция, через которую утекает память, остальные отключал утечка продолжалась, отключил эту - утечки нет. Вот сама функция
Пробовал с использованием strtok - эффект тот же - утечка. Все мозги себе сломал, откуда уткает. OC Linux, сервер Lighttpd Пожалуйста, помогите.
0
|
24.10.2012, 04:38 | |
Ответы с готовыми решениями:
28
Вектор, утечка памяти, функция создания и выделение памяти Утечка памяти Утечка памяти в free() Будет ли утечка памяти? |
Неэпический
|
||||||
24.10.2012, 05:08 | 2 | |||||
В этой функции нет операций работы с памятью, но есть кое что иное.
Сначала Вы ищете подстроку в буфере
Этот буфер, будучи локальным уничтожится после выполнения функции и Ваш возвращенный указатель будет указывать в никуда. P.S. Может, я конечно, что-то упустил, но вроде так
0
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
||||||
24.10.2012, 05:16 [ТС] | 3 | |||||
Если я Вас правильно понял, то вызов этой функции следующий
Вопрос, если все хорошо и ничего не выделется и освобождается, откуда утечка? Уже перепробывал на все локальные переменные free, ничего кроме ошибки не получил, оно и понятно, память ведь не выделялась
0
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
||||||
24.10.2012, 05:29 [ТС] | 5 | |||||
Вот я лох!
Я-то делал
Большущее спасибо!
0
|
Croessmah
|
24.10.2012, 05:30
#6
|
Не по теме: То есть функция GET_ зря отхватила и была отругана понапрасну?
0
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
|
24.10.2012, 05:37 [ТС] | 7 |
Получается, так)))
Недаром задал вопрос в теме для новичков. К тому же раньше и сейчас пишу на php, а там проблем с памятью нет, хотя и возможности существенно ограничены например с той же работой с БД (нет постоянных соединений) Си выбрал полазив по инету, что он легче чем си++ и ненамного быстрее.
0
|
24.10.2012, 09:37 | 8 |
У тебя в функции два массива по 100 килобайт. Это как бы тоже лишняя трата памяти плюс нехорошая нагрузка на операционную систему, потому что сразу появляется несколько страниц в памяти, которые, в основном, не используются. При этом образуются сразу две дырки (два хвоста двух массивов)
Вместо двух массивов лучше использовать alloca, которая выделяет память в стеке. Хуже от этого точно не будет, правда будут лишние вызовы strlen'а На крайний случай вместо двух массивов вполне можно оставить один, что сократит количество дырок до одной. Вместо: C char query[100000], url[100000]; sprintf(url, "&%s", gete); sprintf(query, "&%s=", s); C char buff[100000], *query, *url; int len; url = buff; len = sprintf (url, "&%s", gete); query = buf + len + 1; sprintf (query, "&%s=", s); Добавлено через 3 минуты C strstr(ret_1, "=") C strchr(ret_1, '=')
1
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
||||||
24.10.2012, 13:00 [ТС] | 9 | |||||
Спасибо, Жень!
Только для меня сейчас все это темный лес (стеки, alloca) Понял насчет
Буду разбираться дальше! Кстати, а что за две дырки? Речь идет об уязвимости для хакеров, которые через get-запрос смогут причинить ущерб работе приложения? Думаю (не уверен), лишние strlen'ы ни к чему, сейчас работа этого fastcgi в испытании sieg'ой 350 одновременных запросов за 10 секунд выдает 3,5-3,8 тысячи ответов 200 OK, зато нагрузка на процессор 15-16%, что очень много при весе в оперативке 14 килобайт. Буду думать как уменьшить нагрузку на проц, чтобы запустить этих fcgi больше 1 процесса, не потеряв при этом в производительности.
0
|
24.10.2012, 13:58 | 10 |
Дырки в памяти. Т.е. у тебя выделен массив на 100 килобайт, а в реальности туда пишется несколько десятков или сотен байт. Оставшиеся 99 килобайт по сути дела процесс отожрал, но не использует. Если помножить на 350 параллельных процессов, то получается 35 лиших мегабайт плюс дополнительная нагрузка на подсистему памяти, которая обслуживает неиспользуемые страницы памяти
Значит вернись к этому вопросу потом, когда более-менее с Си освоишься Кстати, вызов strdup - это лишнее действие (и последующий вызов free тоже), поскольку функция GET_ у тебя входные строки не портит, а только читает (а потому нет надобности в их дублировании). Ну и для подстраховки (от собственных ошибок) нужно налепить квалификаторы const. Вместо: C GET_(char *s, char *gete) C GET_(const char *s, const char *gete) Самый быстрый способ пролечить ситуацию - сделать массивы статическими, а не динамическими. Заменить: C char query[100000], url[100000], *ret_1; C static char query[100000], url[100000]; char *ret_1;
0
|
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
|
|
24.10.2012, 14:11 | 11 |
Проще вызывать ф-цию сразу как GET_("&name=",) тогда одно копирование просто выкидываем.
Не он просто проситься на помойку начиная от бессмысленных переменных (flag), циклов, и т.п. и заканчивая алгоритмом. 2TC: если эта ф-ция вызывается более одного раза на запрос (что логично), то можно сразу в месте где Вы делаете getenv() (и я надеюсь, проверяете и декодируете запрос) заменить все '&' на '\0' и запомнить общую длину запроса - это позволит достать любую переменную за 1 цикл. Еще вариант, сразу построить вектор типа argv.
0
|
24.10.2012, 14:42 | 12 |
Дык в том-то и дкло, что в точке вызова лишнего амперсанда у него нет (подаёт-то он наверняка не константную строку, а переменную)
С учётом того, что у автора нет богатого опыта работы на Си, тут всё нормально
0
|
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
|
|
24.10.2012, 14:58 | 13 |
Дык надо дописать
Вряд ли. В 99% случаев имена нужных GET параметров как-раз известны заранее. Решать конечно не нам, а автору, но по-моему это выглядит страшно.
0
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
|
24.10.2012, 15:06 [ТС] | 14 |
Хорошо, а как тогда сохранять значение в переменной функции main?
Спасибо Спасибо, не 350 не параллельных процессов, процесс один, а запросов к fcgi, siege - прога для тестирования серверов. Исходного кода под рукой нет, но если по памяти - то обычный fcgi - читает get, декодирует, обрабатывает mysql_real_escape_string, сравнивает с записями в таблице БД и выдает результат. Стыдно признаться, так я с самого начала и делал, но потом решил немного усложнить задание и чтобы было некоторое удобство при пользовании функцией. В общем учиться, учиться и еще раз учиться
0
|
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
|
|||||||||||
24.10.2012, 15:21 | 15 | ||||||||||
Зря наверное
Вот такая кривулька родилась:
0
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
|
24.10.2012, 15:30 [ТС] | 16 |
Я слабак в Си и еще не спал ночь, так что могу ошибиться
Но почему в env_getvar нужно преждевременно декодировать строку? По-моему тут что-то неправильно. По идее сначала смотрим все QUERY_STRING без декодирования, выбираем из него все %xx грубо говоря, а потом их декодируем. А то пользователь может ввести "&" и тогда мы будем иметь неполный запрос. Может я и ошибаюсь, не знаю. Заранее приношу извинение за возможную глупость в моем высказывании. Просто мозги уже не варят.
0
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
|
24.10.2012, 15:53 [ТС] | 18 |
А можете, если не трудно, меня просвятить, в чем Ваш код лучше-быстрее моего?
Снижена нагрузка на процессор, или увеличена скорость обработки запросов? Просто интересно
0
|
1259 / 650 / 44
Регистрация: 06.02.2011
Сообщений: 1,654
|
|
24.10.2012, 16:07 | 19 |
Leоn, а вот хз - померьте если интересно
Если серьёзно, то Вы не там что-то оптимизировать пытаетесь. Влияние копирования, не как не используемой flag, не нужные циклы и прочего в сумме на производительность/нагрузку стремиться к нулю - Не там ищите. Расставьте замеры времени по коду или погоняйте через профайлер. Не видя кода сказать что-то конретное сложно, но обычно большую часть времени такие вещи тратят на общение с sql. Добавлено через 4 минуты Кстати про %26 и подобные коды в запросе вспомнилось - на предыдущем месте работы было принято _все_ текстовые данные отправляемые клиентом заворачивать в base64 (причем не индексируемые поля так и шли в базу - не тратим время на экранирование/фильтрацию). Довольно удобно, имхо.
0
|
0 / 0 / 0
Регистрация: 02.08.2011
Сообщений: 19
|
|
24.10.2012, 16:27 [ТС] | 20 |
Не, у меня к сожалению base64 не прокатит
А Вы случайно не знаете, [ТС] (то что на моем профиле) на этом форуме что значит?
0
|
24.10.2012, 16:27 | |
24.10.2012, 16:27 | |
Помогаю со студенческими работами здесь
20
Генератор случайного пароля. Утечка памяти Утечка памяти, невозможно обнаружить её самостоятельно Произойдет ли утечка памяти в приведенном фрагменте кода? Утечка памяти в программе, которая считывает и выводит строку Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |