LINUX.ORG.RU

А оно надо?

char *ukozatel;
ukozatel = (char *)malloc(1024);
if(!ukozatel) printf("Где деньги^Wпамять, Зин?\n");
...
if(ukozatel) free(ukozatel);

По-моему такой код вполне валиден...

svr4
()

написать wrapper around malloc, который будет регистрировать указатель в базе и перед free его можно будет там проверить и удалить.

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

typedef void * (*malloc_t)(size_t, const void*);
typedef void (free_t)(void*, const void*);

static malloc_t malloc__;
static free_t free__;

static void * reserve(size_t size, const void * caller) {
    __malloc_hook = malloc__;
    void * ptr = malloc(size + CANARY);
    __malloc_hook = &reserve;
    if (ptr == NULL)
        return NULL;
    memcpy(ptr, __signature, CANARY);
    return ptr + CANARY;
}

static void destroy(void * ptr, const void * caller) {
    if (ptr == NULL || memcmp(ptr - CANARY, __signature, CANARY))
        return;
    __free_hook = free__;
    free(ptr - CANARY);
    __free_hook = &destroy;
}

static void __init(void) {
    malloc__ = __malloc_hook;
    __malloc_hook = &reserve;
    free__ = __free_hook;
    __free_hook = &destroy;
}

void (*__malloc_initialize_hook)(void) = &__init;

rei3er
()

IMHO проще всего написать макрос

#define CHKFREE(x) { if (x) { free(x); x = NULL; } else { printf("Че за фигня?! Иди переписывать код, недоучка!\n); abort(); } }

и просто использовать его вместо стандартного FREE.

no-dashi ★★★★★
()

Перейти на кошерные плюсы и использовать smart pointer'ы

/ме уворачивается от летящих какашек

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

>>#define CHKFREE(x) { if (x) { free(x); x = NULL; } else { printf("Че за фигня?! Иди переписывать код, недоучка!\n); abort(); } }

вот именнно. man 3 free

alex_custov ★★★★★
()
Ответ на: комментарий от T-34

Занулять после free, на уровне инстинктов, чтобы при виде незануленного указателя наступала депрессия до исправления.

wfrr ★★☆
()
Ответ на: комментарий от no-dashi

free(0) вполне нормальная конструкция, которая тупо ничено не делает. Читайте документацию.

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

у него идея -- обнулить указатель, чтобы при повторном free был ноль и грох. Такая дисциплина часто встречается в промышленном коде -- это лучше чем ничего.

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

Мне вот что интересно.

Я недавно писал игрушечную прогаммку на C, и использовал подход, применяемый мною в Java — test first. То есть я писал параллельно 2 файла — файл с юниттестами, в котором тестировал текущий модуль и сам файл с кодом, причём сначала писал тесты, а потом код, реализующий тесты.

Все тесты прогонялись в make-е под valgrind-ом и валились, если valgrind находил какие то ошибки или утечки.

В итоге не тестировались только ситуации, когда malloc возвращает 0 (при желании можно и их было бы тестировать, но было лень) и ощущение уверенности в надёжности кода было куда выше, чем если бы я писал просто так.

Собственно интересно — кто-нибудь такой подход в промышленном C применяет? Или грамотным C-программистам это не надо?

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

>char *ukozatel;
>ukozatel = (char *)malloc(1024);
>if(!ukozatel) printf("Где деньги^Wпамять, Зин?\n");
>...
>if(ukozatel) free(ukozatel);

char *ukozatel;
if(ukazatel) printf("Память будет освобождена!!!\n");

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

мне больше интересно посмотреть на проекты, где вместо free(NULL) используется abort()

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

>Все тесты прогонялись в make-е под valgrind-ом и валились, если valgrind находил какие то ошибки или утечки.

Кстати, был бы любопытно взглянуть на реализацию тестов с использованием valgrind'а. Должно быть не сложно, но всё-таки хотелось бы взглянуть как это реализуют другие разработчики. Покажешь? :)

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

> Кстати, был бы любопытно взглянуть на реализацию тестов с использованием valgrind'а. Должно быть не сложно, но всё-таки хотелось бы взглянуть как это реализуют другие разработчики. Покажешь? :)

было бы куда как интереснее посмотреть на тест план для тестирования некого сервиса, который должен работать 24x7 и в котором где-то в рантайме в зависимости от каких-то нелинейных условий течёт память. по чуть-чуть но со временем накапливается. возьмём в качестве примера ну скажем apache.

// wbr

klalafuda ★☆☆
()
Ответ на: комментарий от php-coder

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

options.h: http://vsb.pastebin.com/m4c882fc7
options.c: http://vsb.pastebin.com/m1809f4df
test_options.h: http://vsb.pastebin.com/m43afaada
test_options.c: http://vsb.pastebin.com/m75d1b239
test.c:  http://vsb.pastebin.com/m55b61430
SConstruct: http://vsb.pastebin.com/m451235c3
src/SConscript-tests: http://vsb.pastebin.com/m42165590

Собственно запуск тестов под valgrind-ом находится в последнем файле.

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

Если мы можем моделировать обстановку, в которой он течёт, пускаем под valgrind-ом, ждём сутки, стопаем и смотрим, что утекло. Если не можем, тогда видимо компилируем с отладочными malloc-ами, отдаём клиенту и анализируем логи, когда начинает течь.

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

Спасибо. (Мне больше последний файл и был интересен..)

php-coder ★★★★★
()

man 3 free:

free() освобождает область памяти, на которую указывает ptr, которая быть выделена ранее посредством malloc(),
calloc() или realloc(). Иначе, если free(ptr) был уже вызван ранее, результат операции не определен. Если ptr
равен NULL, то ничего не происходит.

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

Пиши "free(ptr); ptr=NULL;", если не уверен что будешь освобождать один раз.
А вообще, это немного по-быдлокодерски.

ttnl ★★★★★
()

писать на cyclone. там все подобные проверки опционально в язык добавлены, а выдаёт он в результате вполне себе сишный код

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

>Отчегоже?

Надо всегда знать, что занято, а что освобождено. Иначе это какая-то странная синхронизация.

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

>Надо всегда знать, что занято, а что освобождено.

Вы значит всегда все знаете?

>Иначе это какая-то странная синхронизация.

Какую-то муть вы сказали. Обнуление указателя это способ избежать гниения кода, а не быдлокодерство.

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

> Какую-то муть вы сказали. Обнуление указателя это способ избежать гниения кода, а не быдлокодерство.

не очевидный на самом деле вопрос. да, обнуляя указатели можно в определённой мере застраховаться от того, что если будет больше одного free/delete, то программа по крайней мере не упадёт в корку. с другой стороны, само по себе наличие явного множественного освобождения одного и того же ресурса может быть [и скорее всего является] ошибкой. в этом случае зануление скроет тактическую ошибку но может дать ход стратегической, т.е. вместо того, чтобы просто упать программа будет продолжать что-то делать и уже не факт, что то, что нужно. в общем, есть за есть против.

// wbr

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

>Вы значит всегда все знаете?
Память больше одного раза никогда не освобождаю.

>Какую-то муть вы сказали. Обнуление указателя это способ избежать гниения кода, а не быдлокодерство.

Я писал не про обнуление указателя. Программа, по четыре раза
освобождающая один и тот же указатель - криворукость и быдлокодерство.

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

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

ЕМНИП попытка записи по нулевуму указатели лили чтения вызовет "гарантированную" ошибку доступа по нулевому адресу, если не обнулить то попытка записать что-либо может и не вызвать ошибки - таки аргументы приводятся обычно в книгах.

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

>Я писал не про обнуление указателя. Программа, по четыре раза освобождающая один и тот же указатель - криворукость и быдлокодерство.

Программа не освобождающая его вообще суть идеал?

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

> в этом случае зануление скроет тактическую ошибку но может дать ход стратегической

в приведенном no-dashi примере при повторном free нулевого указателя срабатывает ассерт -- т.е. этот код как раз манифестирует ошибку, в то время как просто двойной фри мог и не вызвать моментальное падение.

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

> ЕМНИП попытка записи по нулевуму указатели лили чтения вызовет "гарантированную" ошибку доступа по нулевому адресу, если не обнулить то попытка записать что-либо может и не вызвать ошибки - таки аргументы приводятся обычно в книгах.

и это то-же в принципе аргумент.

// wbr

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

> ...есть за есть против

ИМХО только против.

Если вы сознательно позвляете себе множественные free/delete, то вам нужен какой-либо вариант GC. Если вы этого не понимаете, то RTFM.

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

> Если вы сознательно позвляете себе множественные free/delete,
> то вам нужен какой-либо вариант GC. Если вы этого не понимаете, то RTFM.

class foo {
public :
    foo() : p_(0) {}

    ~foo() {
        delete []p_;
    }

private :
    int *p_;
};

// wbr

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

добавлю лишь уточнение... например в glib есть функция g_free, так она при попытке освободить уже освободившееся вываливает просесс на double free corruption. так что я стараюсь явно обозначить переменную как NULL после освобождения памяти, ибо если я в каком-то месте сделал free(a), а где-то дальше по коду пытаюсь сделать if (a)... то сие не будет иметь действительную истину.

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

>Программа не освобождающая его вообще суть идеал?

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

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

> если я в каком-то месте сделал free(a), а где-то дальше по коду пытаюсь сделать if (a)... то сие

будет иметь UB, вообще говоря.

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

>Вот это и называется быдлокодерство.

Это называется телепатия, но вам она не удалась, попробуйте еще разок.

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

>Программа не освобождающая его вообще суть идеал?

А в графических программах, по-вашему, надо по несколько раз
инициализировать графическую библиотеку?

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

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

http://www.linux.org.ru/jump-message.jsp?msgid=2642017&cid=2642265

Все.

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

>Это называется телепатия, но вам она не удалась, попробуйте еще разок.

Давайте.
GTK+, наверное, по-вашему надо так инициализировать.

int i;
for (i = 1/*Первая попытка*/; i < 1000; i ++)
if (gtk_init_check (&argc, &argv))
break;

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

Тогда не пишите бреда:


>>Я писал не про обнуление указателя. Программа, по четыре раза освобождающая один и тот же указатель - криворукость и быдлокодерство.

>Программа не освобождающая его вообще суть идеал?


Я внятно озвучил свою позицию, а вы зачем-то совершенно необосновано
стали на меня нападать, сводя мои слова к абсурду.
Я использовал ваш способ, который вам не понравился.

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

>вы зачем-то совершенно необосновано стали на меня нападать, сводя мои слова к абсурду.

Может они изначально обсурдны?

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

> Собственно интересно — кто-нибудь такой подход в промышленном C применяет? Или грамотным C-программистам это не надо?

Мне кажется очень даже надо. То, что работает у программиста на локалхосте, может успешно _не_ работать в других условиях. :)

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

> Вспоминаются пушка и воробей.

Чувствую еще одну жертву высшего образования... :-)

Я говорю про паттерн, а не про совокупность навороченных алгоритмов конкурирующих GC!

Die-Hard ★★★★★
()
Ответ на: комментарий от klalafuda

> в этом случае зануление скроет тактическую ошибку

Зануление указателя гарантирует исключительную ситуацию при попытке повторного обращения к данному указателю, и это на самом деле сильно помогает.

no-dashi ★★★★★
()

Сколько в треде быдлокодеров то спалилось ...

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

>Не так, кроме того у вас плохой стиль, даже одну строчку цикла лучше оборачивать {}.

Вы написали бред. Один из самых правильных стилей программирования -
стиль разработчиков ядра. В коде ядра используются оба способа - без
скобок и со скобками, причем оговаривается, что стиль основывается в
первую очередь на K&R, где скобки как раз не ставятся.

"даже одну строчку цикла лучше оборачивать {}" - это значит? :
___________________________
for (i = 0; i < 10; i ++) {
   link[i] = NULL;
}
===========================

Вот это уже маразм.

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

>Может они изначально обсурдны?

Нет, просто у вас склочный характер.

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