LINUX.ORG.RU

Calloc нынче ни на что не влияет что-ли?

 ,


1

5

MWE:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned char u8;
typedef unsigned int  u32;

#define GB (1024ul * 1024ul * 1024ul)
#define TEST_SIZE (10)

int zerofy = 1;

static u8 * alloc(u32 size)
{
    u8 * res = calloc(size, 1);
    
    if (!res)
    {
        printf(" * Cannot alloc %u bytes\n", size);
        return NULL;
    }
    else
    {
        printf(" * Allocated %u bytes [%p]\n", size, res);
    }

    if (zerofy)
        memset(res, 0, size);

    return res;
}

static void rapemem(u32 zero)
{
    u32 i;
    u8 * p[TEST_SIZE];

    printf("Switching zerofy to %u\n", zero);
    zerofy = zero;

    for (i = 0; i < TEST_SIZE; i++)
        p[i] = alloc(GB);

    for (i = 0; i < TEST_SIZE; i++)
        free(p[i]);
}

int main(void)
{
    system("free -mh");
    printf("\n\n");

    rapemem(0);
    rapemem(1);
    rapemem(0);

    return 0;
}

Выхлоп:

alex@alex-thinkpad-l560:~/Разработка/C/Tests/calloc$ gcc -std=c89 poc.c 
alex@alex-thinkpad-l560:~/Разработка/C/Tests/calloc$ ./a.out 
              total        used        free      shared  buff/cache   available
Память:        7,6G        2,1G        4,2G        396M        1,2G        4,8G
Подкачка:          0B          0B          0B


Switching zerofy to 0
 * Allocated 1073741824 bytes [0x7fe248a9b010]
 * Allocated 1073741824 bytes [0x7fe208a9a010]
 * Allocated 1073741824 bytes [0x7fe1c8a99010]
 * Allocated 1073741824 bytes [0x7fe188a98010]
 * Allocated 1073741824 bytes [0x7fe148a97010]
 * Allocated 1073741824 bytes [0x7fe108a96010]
 * Allocated 1073741824 bytes [0x7fe0c8a95010]
 * Allocated 1073741824 bytes [0x7fe088a94010]
 * Allocated 1073741824 bytes [0x7fe048a93010]
 * Allocated 1073741824 bytes [0x7fe008a92010]
Switching zerofy to 1
 * Allocated 1073741824 bytes [0x7fe248a9b010]
 * Allocated 1073741824 bytes [0x7fe208a9a010]
 * Allocated 1073741824 bytes [0x7fe1c8a99010]
 * Allocated 1073741824 bytes [0x7fe188a98010]
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
 * Cannot alloc 1073741824 bytes
Switching zerofy to 0
 * Allocated 1073741824 bytes [0x7fe248a9b010]
 * Allocated 1073741824 bytes [0x7fe208a9a010]
 * Allocated 1073741824 bytes [0x7fe1c8a99010]
 * Allocated 1073741824 bytes [0x7fe188a98010]
 * Allocated 1073741824 bytes [0x7fe143fff010]
 * Allocated 1073741824 bytes [0x7fe103ffe010]
 * Allocated 1073741824 bytes [0x7fe0c3ffd010]
 * Allocated 1073741824 bytes [0x7fe083ffc010]
 * Allocated 1073741824 bytes [0x7fe043ffb010]
 * Allocated 1073741824 bytes [0x7fe003ffa010]

WTF вообще? Теперь и calloc выделению доверять нельзя? Да здравствуют SIGSEGV без вариантов проверить выделение?

Я знаю про оптимистичное выделение, но всю жизнь эта ботва была только с malloc, calloc от этой херни был свободен так как занулял память.

★★★★★

Последнее исправление: PPP328 (всего исправлений: 1)

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

надо? создай

Ну так я тебя и спрашиваю. Будешь там ныть?

под space-ом должен лежать storage

А еще компьютер должен быть подключен к источнику питания от радиоизотопных генераторов с рассчётным сроком службы не менее 50 лет и надежно забетонирован в бункере, чтобы не пришел злой админ и не нажал reset.

в стандарте об этом говорится как-то невнятно, согласен

Да, про радиоизотопные генераторы в стандарте как-то смазано написали, согласен.

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

отсутствие навыков чтения документации — это прискорбно:

The malloc() function shall fail if:

[ENOMEM] Insufficient storage space is available.

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

отсутствие навыков чтения документации — это прискорбно:

Согласен.

The malloc() function shall fail if:

[ENOMEM] Insufficient storage space is available.

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

Только прикол в том, что без квот с включенным оверкоммитом хрен когда это произойдет!

Ну выдели N раз по 500 MiB в 32-битном процессе, узнаешь этот «хрен».

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

Блин, я не про 32-битный линукс, а про железо!

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

anonymous
()

знаю про оптимистичное выделение, но всю жизнь эта ботва была только с malloc, calloc от этой херни был свободен так как занулял память.

Это, конечно, не так. calloc обещает зануленную память, но не обещает, что будет занулять ее сам. Если система гарантирует выделение зануленной памяти (а она это гарантирует), calloc не трогает память.

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

Это каким олухом надо быть, чтобы 32-битную систему ставить на 64-битную машину?

А 32-битный процесс можно скомпилять и на 64-битной машине, не зря же abi32 вкорячены.

Только не будем всякие фантастические варианты рассматривать. Я говорю о том, что на обычной машине вероятность того, что malloc вернет NULL, стремится к нулю!

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

А 32-битный процесс можно скомпилять и на 64-битной машине, не зря же abi32 вкорячены.

Молодец.

Только не будем всякие фантастические варианты рассматривать. Я говорю о том, что на обычной машине вероятность того, что malloc вернет NULL, стремится к нулю!

А когда-то памяти было 64 килобайта. И никакой «виртуальной», одна физическая. Прикинь.

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

какие буквы в слове «storage» ты не смог прочитать?

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

Я правильно понимаю что саму модель ты не опишешь?

К сожалению, некому описывать. Царь всех затралил и все совершили массовый уход с ЛОРа из-за него. Даже квазимото. Даже алексотт. Даже саныч. Даже рут. Даже антихрист.

Один царь остался.

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

Я пока в каждом сообщении вижу что то про шизофрению и какие то рассуждения о смысле жизни что тебя не понимают

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

Царь хочет так же в программировании. Чтобы было просто-препростро и быстро-пребыстро.

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

А сама модель, самое представление должно обладать наиболее полной интеграцией в себя нюансов реальности. А в более простых вариациях это всё должно заменяться на умолчания.

В знак благодарности за царево откровение предлагаю совершить массовый уход с ЛОРа. Два раза.

anonymous
()

Объясни немножко далёкому человеку: проблема в том, что calloc не зануляет выделяемую память?

Или чё?

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

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

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

Если примитивно:
Вы просите память через malloc/calloc.
Вам дают указатель.
Вы по нему пишете.
Программа падает.
??
PROFIT!!

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

Объясни немножко далёкому человеку: проблема в том, что calloc не зануляет выделяемую память?

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

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

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

Твой вариант, ЯННП не понял, кто возвращает то ли невалидный указатель, то ли указатель на незануленную память.

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

А какие механизмы за этим стоят и почему?

Царь кому пять страниц объяснял?

Механизмы Реального Мира за этим стоят! За эталон Реального Мира, конечно же, принимается хлам, который крутится у Царя дома - его железо, его ядро и его библиотеки.

Если хочешь быстро и правильно, ты обязан писать проги только под цареву систему. Должен прийти к нему домой, сесть на табуретку и писать. А когда Царь обновит ядро или поменяет какую-то железку, придешь и перепишешь прогу заного, под Новую Реальность.

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

Твой вариант

Настройки ядра таковы, что оно выделяет больше памяти, чем у него есть - фактически оно увеличивает размер адресного пространства процесса, но реальной памяти не выделяет (для простоты, считай, что таблица страниц процесса заполняется page entries с невалидным значением). Приложение пытается обратится к адресу памяти, который соответствует невалидному page entry - в этом случае ядро обязано выделить память или вынуждено будет прибить процесс. Если памяти не хватает, приложение получает фатальный сигнал.

Поведение ядра спорное, но, увы, сейчас считается нормальным.

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

Давай, расскажи мне больше.

Я не говорил, что прогрессивный мир в большинстве. Легаси тоже надо поддерживать.

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

Хоть один надмозг ЛОРа нормально рассказал :-)

Спасибо!

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

мы говорили про систему. при чём тут система? не надо тут стрелки переводить.

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

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

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

виртуальная память - вообще не память

Виртуальная память - это именно память. Она поддерживается своп-файлом или реальной физической памятью.

вы можете себе гигабайты выделять, даже если их нет у машины

Это рост адресного пространства, а не выделение памяти.

если это не противоречит безопасности и страница принадлежит процессу, ничего не будет зануляться

Если страница уже принадлежит процессу, речь о ее выделении вообще не идет.

и уж ядно-то я читала поболее, чем многие

Вот это совершенно верно. Ты точно читала больше, чем миллиард (или сколько их там сейчас) неграмотных жителей Земли %)

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

Она поддерживается своп-файлом или реальной физической памятью.

ага. запусти софт, который выделит 500 гигов, чо мелочиться-то - на винте места много! и потом погляди, как у тебя система будет ворочаться со свопа. всё это от говнопрограммирования пошло. и ни к чему хорошему не ведёт. мало читать - надо ещё головой думать, однако.

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

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

Действительно, Committed_AS существует. Значит я его в прошлый раз просмотрел т.к. его существование имеет крайне мало смысла.

Я точно знаю, что оно с ним падает. Опять же - не знаю и мне лень смотреть на то - как оно работает с шаредмемом.

Если его (порог) настроить, ядро начнёт отказывать в выделении страниц раньше, чем наступает срабатывание ООМ-киллера. Это именно то, чего тут всякие Эдди требуют сделать «как в винде».

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

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

Приложение пытается обратится к адресу памяти, который соответствует невалидному page entry - в этом случае ядро обязано выделить память или вынуждено будет прибить процесс. Если памяти не хватает, приложение получает фатальный сигнал.

Такого поведения нету.

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

Страницы, которым потенциально потребуется COW, он считает по пессимистичному варианту. Так что это реально мрак.

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

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

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

Очень сильно смахивает на анскилл.

если это не противоречит безопасности и страница принадлежит процессу

Никакая страница не принадлежит процессу. Страницы существуют совершенно с другой стороны. Процессу только принадлежит «вообще не память» и данные.

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

Будет и зануляет. Ну и я тут вынужден ещё раз диагностировать явный анскилл, который не позволяет человеку даже понять то, о чём тут вообще говорят.

Для справки - никакого не волнует зануление, всех волнует побочный эффект зануления мемсетом, а именно «деревенский» префолт.

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

ага. запусти софт, который выделит 500 гигов

Для справки - выделяют эти 500гигов не для того, чтобы их заполнить свопом. Вас запутали. Эти 500гигов могут быть разрежённые. Это много где бывает полезно.

В основном подобное поведение используется для отслеживания обращений к памяти. cow, автоматическое расширение и прочее. Сотни процессов, тысячи потоков и у каждого свой. А каждый стек по 8метров, а система раком не встаёт. Но то у говнопрограммистов, а у профессионалов встаёт. Отличные профессионалы.

Да и нахрен нужен cow - сразу копируем всю память при форке, как поступают настоящие профессионалы. Нахрен аллоцировать 500гигов «совсем не памяти» ммапом - надо стать раком и читать файлы ридом.

Какой же он прекрасный мир, мир профессионалов. Как хорошо, что я в нём не живу.

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

Это рост адресного пространства, а не выделение памяти.

Ну так нельзя в таком великонаучном споре опускаться в такую вульгарщину. Адресное пространство определяется битностью. Царь, слаще 286 и 386 не видевший, может вам даже расскажет, что раз на x86 больше 3G на процесс просто так не получишь, то это и есть Велика Реальность 32-битности. :)

При запросе sbrk/mmap(dev/zero|anon) происходит рост разрешённых ОС для доступа конкретному процессу границы виртуального пространства или страниц виртуального пространства соответственно. Можно получить доступ к реальной памяти, например к видеобуферу, это когда-то даже делалось типа так: map=ioctl(0,MAPVGA,0); на SCO/MS Xenix, да даже mmap к физическому файлу не «расширяет адресное пространство», а опеределяет, что вот этот кусок пространства теперь связан с.

Поведение ядра спорное, но, увы, сейчас считается нормальным.

Вполне возможно это такое «не мытьём, так катанием» продвижение изменения, чтобы наконец дошло, что стандарты со времен 64k/процесс поменялись, и пора сделать malloc_spare() ? То есть дополнительный флаг у mmap? Пока без этого флага — работаем с имеющейся памятью: физика+своп, убиваться по доступу к ранее неинициализированной памяти — нельзя. Хотите дырявую память — так пожалуйста, юзайте вот этот spare и будьте готовы, что при первом обращении к памяти, выделенной именно этим методом можете в любой момент подохнуть. Делать ли такой malloc_spare псевдонимом к malloc будет определяться дистрибутивом :)

Пока же имеем «настройку» vm для всей системы целиком и malloc_spare=malloc и живём с этим :(

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

виртуальная память - вообще не память

Виртуальная память - это именно память. Она поддерживается своп-файлом или реальной физической памятью.

ага. запусти софт, который выделит 500 гигов, чо мелочиться-то - на винте места много! и потом погляди, как у тебя система будет ворочаться со свопа

При попытке использовать эти 500G ты получишь поведение, называемое «thrashing». Оно описано в книгах, которые ты якобы читала.

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

на SCO/MS Xenix, да даже mmap к физическому файлу не «расширяет адресное пространство», а опеределяет, что вот этот кусок пространства теперь связан с.

А память, с которой этот кусок был связан раньше, просто исчезает?

чтобы наконец дошло, что стандарты со времен 64k/процесс поменялись, и пора сделать malloc_spare() ?

Зачем?

То есть дополнительный флаг у mmap?

Это уже давно есть.

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

А память, с которой этот кусок был связан раньше, просто исчезает?

Ну здрасти. Не вы ли тут всех шпыняете, чтобы не путали память/пространство? Что куда может исчезнуть? У процесса есть виртуальное пространство с некой разрядностью, в этом пространстве есть (совсем не обязательно последовательно) куски с разрешением к доступу или нет, в том числе и путём добровольного отказа.

Зачем?

Вы не понимаете длинных рассуждений? Весь текст там был о «зачем».

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

на SCO/MS Xenix, да даже mmap к физическому файлу не «расширяет адресное пространство», а опеределяет, что вот этот кусок пространства теперь связан с.

А память, с которой этот кусок был связан раньше, просто исчезает?

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

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

Зачем?

Вы не понимаете длинных рассуждений?

Очевидно, что я не понимаю твоих длинных рассуждений. А ты явно не можешь ответить на вопрос «зачем».

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

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

Кто «он» исчез? Под расширением можно, кстати, рассматривать метод расширения виртуального пространства от 2 до 3 Гб на 32-битных системах. Это да, но это только лишнее доказательство убогости I86.

Очевидно, что я не понимаю твоих длинных рассуждений.

Ренее было очевидно, что вам нетерпелось ответить, выплюнув в типичной манере ЛОРа — набор коротких хамских «вопросов с подковыркой», на который вы на самом деле и не ждёте ответов, без какого-либо усилия по вниканию в текст, который «комментируете».

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

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

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