[C] Выделение памяти со статистикой

Для тех, кто хочет сделать мир лучше.
Сообщение
Автор
Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#1 Сообщение 02.08.2011, 21:57

Написал пару обёрток на C для функций malloc, realloc и free.
Пригодилось мне уже в одном проекте, и я подумал, что будет неплохо поделиться.

Возможности:
  • Учёт статистики, а именно структура данных с пятью полями - количество байт при последнем выделении памяти; количество выделенных байт на текущий момент времени; максимальное число байт, выделенных за один раз; максимальное выделение памяти за время работы программы; количество байт, когда-либо выделенных в программе с момента запуска.
  • Дополнительная информация о блоке памяти. Можно узнать, сколько байт сейчас выделено под какой-либо объект.
Функции:
Первые три эквивалентны функциям malloc, realloc, free. Отличия выделены жирным.
  • smalloc
    Принимает размер в байтах, выделяет память и возвращает указатель на выделенную область памяти. В случае неудачи печатает сообщение об ошибке в stderr и завершает программу.
  • srealloc
    Принимает указатель для перевыделения и размер в байтах, возвращает указатель на выделенную область памяти (уменьшенную или увеличенную, сохраняя данные). Если указатель == NULL, то вызывает smalloc c нужным размером. В случае неудачи возвращает старый указатель, не давая случиться утечке памяти.
  • sfree
    Принимает указатель на область памяти, освобождает его, ничего не возвращает.
  • getmemsz
    Принимает указатель на область памяти, возвращает количество выделенных байт.
  • print_stats
    Выводит в stderr статистику выделений памяти такого вида:

    Код: Выделить всё

    Last allocation: 100 bytes
    Currently active: 450 bytes
    Biggest allocation: 200 bytes
    Maximum memory usage: 600 bytes
    Allocated in total: 10900 bytes
Скачать:
В архиве исходники, пример программы, использующей s_alloc, и скомпилированные бинарники этой программы для Windows и Linux.
  • s_alloc.zip
    (19.51 КБ) 153 скачивания
    s_alloc.zip
    (19.51 КБ) 153 скачивания
  • [url]svn://night-leshiy.ru/NiGHt-LEshiY/handy%20tools/s_alloc/[/url]
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
$t@t!c_V()1D
Разработчик
Разработчик
Сообщения: 2639
Зарегистрирован: 06.12.2007
Благодарил (а): 10 раз
Поблагодарили: 29 раз

#2 Сообщение 03.08.2011, 08:11

Милая штука, но
NiGHt-LEshiY писал(а):В случае неудачи возвращает старый указатель, не давая случиться утечке памяти.
меня как-то смущает - может, как-то проверять, что изменение массива произошло (через доп функцию вроде WinAPI-шной GetLastError() или через второе возвращаемое значение)?

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#3 Сообщение 03.08.2011, 10:29

А причем здесь винапи?
Мне кажется, что такое поведение оправдано. Если ты хочешь увеличить размер выделенного блока памяти с 10 мегабайт до, скажем, 20, то в случае неудачи realloc вернет NULL. В итоге память не расширена, а указатель на старый блок памяти утерян.
srealloc не должен позволить такому случиться и поэтому нет нужды заводить лишний "резервный" указатель и городить прочие костыли %)

После выполнения функции все еще можно узнать, что тебе отдали старый указатель. Во первых, проверить переменную errno. Во вторых, использовать getmemsz для получения текущего размера блока.
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Аватара пользователя
$t@t!c_V()1D
Разработчик
Разработчик
Сообщения: 2639
Зарегистрирован: 06.12.2007
Благодарил (а): 10 раз
Поблагодарили: 29 раз

#4 Сообщение 03.08.2011, 13:34

NiGHt-LEshiY писал(а):А причем здесь винапи?
Я имел в ввиду "приделать функцию наподобие". А про getmemsz() сначала подумал по привычке, как про GetMem() в Delphi - бывает. Прошу прощения, претензии отменяются.

Аватара пользователя
NiGHt-LEshiY
Полковник
Полковник
Сообщения: 10258
Зарегистрирован: 13.06.2008
Откуда: Россия
Благодарил (а): 752 раза
Поблагодарили: 2667 раз
Контактная информация:

#5 Сообщение 03.08.2011, 14:09

Там же написано ;)
Вообще, по стандартам, нужно смотреть errno. Благо исходник компилится под Linux/Windows/FreeBSD без модификаций.
Кодекс поведения участников сообщества — обязательно к прочтению.
Просьба присылать сообщения об ошибках в ЛС.

Ответить Вложения 1