LINUX.ORG.RU

сейчас цАРЬ нам расскажет что realloc-fail не может быть потому что не может быть malloc-fail)))

anonymous
()

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

anonymous
()

Часто, при исчерпании памяти проще умереть, как-то так:

void *e_realloc(void *ptr, size_t size)
    {
    void *res;

    res = realloc(ptr, size);

    if(NULL == res)
        {
        perror(NULL);
        exit(EXIT_FAILURE);
        }

    return res;
    }
И если e_realloc вернулся, значит память есть, и результат проверять не нужно.

Такое решение подходит, например, для утилит командной строки.

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

тебя то-же цАРЬ покусал? мало того что бред про malloc, так еще и плевать на другие внешние ресурсы

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

мне кажется, это вопрос правильной архитектуры

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

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

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

сетевые клиенты/серверы

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

не зафлушенные данные

не факт, что удастся сохранить а не испортить при отсутствии памяти.

и тд и тп.

если реально есть такие ресурсы (например SYSV IPC), они должны освобождаться в atexit().

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

нужно обрабатывать код возврата а не городить лапшу из exit(), atexit() и функций освобождения в разных подсистемах - это все говнокод

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

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

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

arturpub ★★
()

ПРИШЛО ВРЕМЯ ОСВОБОДИТЬ ПАМЯТЬ ПАМЯТЬ САМА НЕ ОСВОБОДИТСЯ

anonymous
()

Классика из man realloc(3):

     When using realloc() be careful to avoid the following idiom:

           size += 50;
           if ((p = realloc(p, size)) == NULL)
                   return (NULL);

     Do not adjust the variable describing how much memory has been allocated
     until the allocation has been successful.  This can cause aberrant
     program behavior if the incorrect size value is used.  In most cases, the
     above sample will also result in a leak of memory.  As stated earlier, a
     return value of NULL indicates that the old object still remains
     allocated.  Better code looks like this:

           newsize = size + 50;
           if ((newp = realloc(p, newsize)) == NULL) {
                   free(p);
                   p = NULL;
                   size = 0;
                   return (NULL);
           }
           p = newp;
           size = newsize;

     As with malloc() it is important to ensure the new size value will not
     overflow; i.e. avoid allocations like the following:

           if ((newp = realloc(p, num * size)) == NULL) {
                   ...

PS: читайте правильные маны, а не это gnu-гуано.

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

А я всегда к запросу добавляю «opengroup», так голова не нагружается локальным фольклором.

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

А можно эти правильные маны в линуксы поставить?

Можно, этот правильный линукс называется опербсд. ;)

А вообще, вон лёня уже и до манов добрался. То ли ещё будет ой-ой-ой.

beastie ★★★★★
()
Последнее исправление: beastie (всего исправлений: 1)
Ответ на: комментарий от beastie

В этом твоем правильном линуксе даже nm. Ни о гуйце к нему, ни о пульсе с systemd (ладно, толсто), ни о дровах к свежей вафле, ни о нормальных ФС, ни о UEFI я не говорю

Я конечно понимаю, что зажрался и консолька рулит, но я действительно зажрался

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 3)
Ответ на: комментарий от beastie

If realloc() fails the original block is left untouched; it is not freed or moved.

Предубеждение против GNU заставляет тебя пропускать фразы, которые ты не хочешь там видеть. IMHO в данном случае правильный вариант — в GNU man странице: это справочник, а не учебник.

i-rinat ★★★★★
()

Сабж. Только вариант с дополнительной переменной есть или есть что-то менее быдлокодистое?

glibc + linux. Реалок фейлануть не может в принципе.

В хипе самого маллока фейла реалока просто быть не может по определение, если фейл и будет - он будет внутри реалока.

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

Ещё оно может фейлануть когда ты реалочишь из хипа маллока в ммап, но упадёт оно тоже в самом реалоке.

Т.е. фейл может случится только тогда, когда ты сделаешь(допустим у тебя 32гига памяти и не свопа) realloc(ptr, 1024*1024*1024*35ul) - насколько ты понимаешь - такого никогда не бывает.

Т.е. с шансом 1% - оно тебе вернёт фейл, а шансом 99% оно упадёт от sigkill.

Теперь подумай о надёжности.

А самое интересное - я тут решил прочитать мануал и так руским/английским написано то, о чем я говорю. Т.е. тут все не просто анскилыши нулёвые, дак к котомуже даже мануала не читали:

По умолчанию, Linux придерживается оптимистичной стратегии распределения памяти. Это означает, что когда malloc() возвращает значение не NULL, то нет никаких гарантий, что память в действительности доступна. Если обнаружится, что системе не хватает памяти, то один или несколько процессов будут завершены OOM.
anonymous
()
Ответ на: комментарий от arturpub

Против царя тут все только потому, что прога должна падать в момент ошибки, а не через пару секунд и в совершенно другом фрейме, где уже концов не найти

Как связана твоё «не через пару секунд» с царём?

Какраз-таки царь и говорит, что говно питушков с шансом 99% просто упадёт, чем вернёт какую-нибудь ошибку. И при этом царь рассказывал как делать так, чтобы 100% отслеживать память и получать ошибку.

Так же царь говорил, что нет смысла проверять ошибку, если с шансом 99% тебе вернётся !null, а прога всё равно упадёт.

Если уж ты проверяешь ошибки - делай так, чтобы твоё говно не падало форфан без ошибок с sigkill. Либо хоятбы шанс должен быть <=50%, а не в районе 99% как у рядовой обезьяны.

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

Т.е. с шансом 1% - оно тебе вернёт фейл, а шансом 99% оно упадёт от sigkill.

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

я тут решил прочитать мануал

а ты что этого не знал? дурилка ты картонная)))

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

Позволь не согласиться: явные указания на проблемы и пути решения, связанные с bad habbits, тоже справочник.

  • В GNU-man'е пропустить это — пить дать.
  • В BSD-man'е уже так просто не пропрустишь.

И скажи мне после этого, какой из справочников более граматный.

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

ок, так и быть, *bsd годится как набор манов

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

Всяк кулик своё болото хвалит.

Я в обоих man'ах бы это пропустил, ибо никогда не читаю страницу полностью. И, судя по выкладываемым на форуме кускам кода, эти страницы вообще мало кто читает.

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

похоже на баттхерт

Да не, я попкорном запасался.

// не царь

Дожили.

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

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

Мне вот интересно, аноним, ты на самом деле _тестируешь_ свой софт на предмет возврата NULL из malloc'a?

Ну т.е., например, через gdb симулируешь возврат NULL и смотришь, что получится? Или лишь бы ляпнуть проверку на NULL, а дальше, судя по коду, оно нормально отработает?

Я, собственно, к чему. Если памяти действительно не хватило и хорошо, если ты узнал об этом через NULL от malloc/realloc. Но даже в этом случае шансов нормально все разрулить и выйти не много (успеть хотя бы написать что-то в лог).

Dead ★★★★
()
Последнее исправление: Dead (всего исправлений: 2)
Ответ на: комментарий от Dead

Мне вот интересно, аноним, ты на самом деле _тестируешь_ свой софт на предмет возврата NULL из malloc'a?

Конечно. И обрабатываю все ошибки и тестирую, так делает любой программист в отличие от быдлокодеров типа цАРЯ.

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

зачем gdb? открой для себя /proc/sys/vm/overcommit_memory и ulimit. с ulimit цАРЯ уже доказательно опустили в той теме про malloc

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

кроме того можно сделать свои malloc/realloc и загружать через LD_PRELOAD

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

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

PS. Сам я стараюсь проверять результат malloc-а, т.к. не знаю тонкостей всех систем, на которых собирается программа и тем более не знаю, как эти тонкости изменятся в будущем, т.е. считаю полезным попытаться выдать корректное сообщение об ошибке вместо невнятного сегфолта. Но если рассматривать только линукс и только сейчас, царь прав на сто процентов.

PPS. А по теме, я писал функцию-обертку по типу бсдшной.

staseg ★★★★★
()

А смысл? Не так уж и много можно придумать ситуаций, когда в случае неудачи malloc/realloc имеет смысл продолжать работу программы, а не убить ее нахрен (ну или перезапустить в случае демона).

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

Не так уж и много можно придумать ситуаций, когда в случае неудачи malloc/realloc имеет смысл продолжать работу программы

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

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

И обрабатываю все ошибки и тестирую

+100500

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

Ну, не знаю. У меня задачки простые, но им память нужна. И если памяти "вдруг" не стало, то и задаче нет смысла висеть. Харакири.

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

Но если рассматривать только линукс и только сейчас

откуда ты знаешь где и как запущена программа? может там overcommit_memory == 2

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

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

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

Сеть

ОК, здесь запросто: памяти нет → шлем очередных клиентов лесом.

связанные процессы

убиваем сразу всех. Ну, если вдруг один может подождать, то да — можно и не убивать.

память, что была выделенна ранее

?

закрытие файловых дескрипторов

?

работа с внешними устройствами

нет памяти для буфера, чтобы принять данные → самоубийство решит проблему. Или этими данными можно пренебречь?

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

убиваем сразу всех.

Дык мы ж вышли по exit, как мы их убьем?

память, что была выделенна ранее

?

Что значит "?"? Т.е. хапнули 2 Гб, хапнули еще 4кб, 4кб зафейлилось, кто 2 Гб освобождать будет? Пушкин?

закрытие файловых дескрипторов

?

Стандартный виндовый пример - «файл не может быть открыт так как файл занят другим процессом». Часто не разлочивался после внезапного убийства процесса.

Или этими данными можно пренебречь?

Плевать на данные. Если это станок, то его перед харакири надо выключить или харакири внезапно сделает либо кто-то о станок либо сам станок от перегрева etc.

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

мы ж вышли по exit, как мы их убьем?

Сначала убиваем, потом — харакири. Если, конечно, oom-killer раньше не подоспеет.

кто 2 Гб освобождать будет?

Ведро, ясен пень. На кой хрен вызывать free перед выходом из программы?

файл не может быть открыт так как файл занят другим процессом

Такое бывает? O_o...

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