sub join( $separator, @strings ){
my $return = shift @strings;
for @strings -> ( $string ){
$return ~= $separator ~ $string;
}
return $return;
}
Да, я знаю это, бессмыслен, потому что Perl 6 уже имеет функцию соединения.
Это не стандартно, но если в вашей библиотеке есть функция msize ()
, которая даст вам размер.
Распространенное решение - обернуть malloc
с вашей собственной функцией, которая регистрирует каждый запрос вместе с размером и результирующим диапазоном памяти, в сборке выпуска вы можете вернуться к «реальному» malloc
.
Библиотека времени выполнения C не предоставляет такие функция. Более того, намеренное создание исключения также не скажет вам, насколько велик блок.
Обычно способ решения этой проблемы в C состоит в том, чтобы поддерживать отдельную переменную, которая отслеживает размер выделенного блока. Конечно, иногда это неудобно, но обычно нет другого способа узнать.
Ваша библиотека времени выполнения C может предоставлять некоторые функции отладки кучи, которые могут запрашивать выделенные блоки (в конце концов, free ()
необходимо знать, насколько велик блок), но что-либо подобное будет непереносимым.
С gcc
и компоновщиком GNU
вы можете легко обернуть malloc
#include <stdlib.h>
#include <stdio.h>
void* __real_malloc(size_t sz);
void* __wrap_malloc(size_t sz)
{
void *ptr;
ptr = __real_malloc(sz);
fprintf(stderr, "malloc of size %d yields pointer %p\n", sz, ptr);
/* if you wish to save the pointer and the size to a data structure,
then remember to add wrap code for calloc, realloc and free */
return ptr;
}
int main()
{
char *x;
x = malloc(103);
return 0;
}
и скомпилировать с
gcc a.c -o a -Wall -Werror -Wl,--wrap=malloc
(конечно, это также будет работать с кодом C ++, скомпилированным с g ++, и с оператором new (через его искаженное имя), если хотите.)
Фактически, статически / динамически загружаемая библиотека также будет использовать ваш __ wrap_malloc
.
Если вы не против грубого насилия ради отладки, вы можете #define макросов для перехвата вызовов malloc, освобождения и заполнения первых 4 байтов размером.
Чтобы мелодия
void *malloc_hook(size_t size) {
size += sizeof (size_t);
void *ptr = malloc(size);
*(size_t *) ptr = size;
return ((size_t *) ptr) + 1;
}
void free_hook (void *ptr) {
ptr = (void *) (((size_t *) ptr) - 1);
free(ptr);
}
size_t report_size(ptr) {
return * (((size_t *) ptr) - 1);
}
, затем
#define malloc(x) malloc_hook(x)
и так далее
Нет, и вы не можете полагаться на исключение при выходе за его границы, если это не указано в документации вашей реализации. Это часть того, о чем вам действительно не нужно знать при написании программ. Изучите документацию или исходный код вашего компилятора, если вы действительно хотите знать.
Средства проверки памяти, такие как memcheck Valgrind и TCMalloc от Google (часть проверки кучи) ) отслеживать подобные вещи.
Вы можете использовать TCMalloc для дампа профиля кучи, который показывает, где что-то было распределено, или вы можете просто проверить, чтобы ваша куча была одинаковой в двух точках выполнения программы, используя SameHeap () .
Частичное решение: в Windows вы можете использовать PageHeap для отслеживания доступа к памяти за пределами выделенный блок.
PageHeap - это альтернативный менеджер памяти, присутствующий в ядре Windows (в разновидностях NT, но в настоящее время никто не должен использовать какую-либо другую версию). Он берет каждое выделение в процессе и возвращает блок памяти, конец которого совмещен с концом страницы памяти, а затем делает следующую страницу недоступной (без чтения, без доступа для записи). Если программа попытается прочитать или записать за конец блока, вы получите нарушение прав доступа, которое вы можете поймать с помощью вашего любимого отладчика.
Как это получить: Загрузите и установите пакет Debugging Tools for Windows от Microsoft: http://www.microsoft.com/whdc/devtools/debugging/default.mspx
, затем запустите утилиту GFlags, перейдите на третью вкладку и введите имя исполняемого файла, затем нажмите клавишу. Установите флажок PageHeap, нажмите OK, и все готово.
И последнее: когда вы закончите отладку, никогда не забудьте снова запустить GFlags и отключить PageHeap для приложения.
Для этого не существует стандартной функции C. В зависимости от вашей платформы может быть непереносимый метод - какую ОС и библиотеку C вы используете?
Обратите внимание, что вызов исключения ненадежен - могут быть другие выделения сразу после имеющегося у вас фрагмента, поэтому вы можете не получить исключение, пока вы не превысите пределы текущего блока.
Чтобы сделать то, что вы хотите, нужно БЫТЬ распределителем . Если вы отфильтруете все запросы, а затем запишите их для целей отладки, вы сможете узнать, что вы хотите, когда память будет освобождена.
Кроме того, вы можете проверить в конце программы, все ли выделенные блоки были освобождены, и, если нет, перечислить их. Такая амбициозная библиотека может даже принимать параметры FUNCTION и LINE через макрос, чтобы вы точно знали, где происходит утечка памяти.
Наконец, MSVCRT от Microsoft предоставляет отлаживаемую кучу с множеством полезных инструментов, которые вы можете использовать в отладочной версии для поиска проблем с памятью: http://msdn.microsoft.com/en-us/library/bebs9zyz.aspx
Вкл. Linux, вы можете использовать valgrind, чтобы найти множество ошибок. http://valgrind.org/