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)
Ответ на: комментарий от pftBest

Давайте во все устройства ставить не мипсы и армы по 1$ штука, а штеуды за 100$.

Что-то ты фигню несёшь. За 1$ ты ничего не купишь. И штеуды тут не причём. Ты наверное перепутал свою мкашку и нормальный процессор, ну дак вот - я тебя удивлю, но тут лор, тут контекст линукс. Линукс не работает на помойке на 1доллар без мму.

А армы уже перешли на 64бита, скоро и все остальные перейдут. Не волнуйся. К штеуду это не имеет никакого отношения.

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

Не, не, не. Ты не пытайся таким глупым образом юлить.

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

А почему реаллок не нужен - я уже давно рассказал и не один раз. Давайте вы уже перестанете подобными манипуляциями заниматься?

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

Это когда армы на 64 бита перешли? И где мне купить «апельсинку» на 16-ядерном 64-битном арме?

Жаль, загубили мипсы. А то реально можно было бы недорогой 128-битный 128-ядерный одноплатничек прикупить в перспективе…

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

Это когда армы на 64 бита перешли?

Уже много лет как. https://en.wikipedia.org/wiki/Comparison_of_ARMv8-A_cores и далее.

И где мне купить «апельсинку» на 16-ядерном 64-битном арме?

Что такое «апельсинка»? Какой-то одноплатник? Скорее всего уже есть - гугли. 64бит - это не про ядра.

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

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

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

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

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

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

Вон еще на первой странице кто-то жаловался, что ему надо «как в винде». Ну так пусть настроит как в винде. Нет, лучше поныть на форуме.

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

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

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

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

Ты неправильно понял. Я именно говорю о том, что эта новая концепция уже есть. Старая же - не концепция железа/памяти/ОС, а именно модели описывающие память, ОС, железо.

Т.е. концепция понимания, концепция создания отображающих реальные вещи моделей. Сейчас у нас есть модели на базе калькуляторов 100летней давности, да даже не «живых», а абстрактных.

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

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

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

Я правильно понимаю что саму модель ты не опишешь? ;) Мне интересно (правда) услышать что это за модель. Без сравнений и без шизофрений в тексте.

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

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

Модель чего? Что значит опишешь? Я правильно понимаю что старую/текущую модель ты не опишешь?

Мне интересно (правда) услышать что это за модель.

Я тебе уже описал их свойства и то, что их должно отличать от текущих. Т.е. описание того, что это за модель - тебе дали. Если тебе что-то непонятно - ты описываешь чётко и ясно то, что тебе не понятно и что в твоём понимании описание и как это описание должно выглядеть.

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

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

Опиши ни с чем ни сравнивая, потому что я не в курсе что там на калькуляторах и 286 было. Расскажи как сейчас мир устроен. Я пока в каждом сообщении вижу что то про шизофрению и какие то рассуждения о смысле жизни что тебя не понимают

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

Чем плохо работать с памятью через Malloc

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

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

Т.е. маллок делает и возврщает и гаранатирует совершенно не то, что ты от него ждёшь. И проблема в том, что ты ждёшь не то, что нужно.

Именно поэтому и надо + есть нюансы по производительности и удобству - всё это даёт новые возможности, те, которых не даёт дефолтное предсавленеи и дефолтные механизмы. И люби пишут всякие там санитайзеры и прочее на этих принципах. Мне лень одно и то же 10раз повторять.

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

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

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

потому что я не в курсе что там на калькуляторах и 286 было.

Было так как описано в любой макулатуре и мануалам по маллоку. Про калькуляторы и 286 я говорил в том контексте, что эти описании в те времена хоть как-то налазили на железяку. К ним я никак не апеллирую.

Расскажи как сейчас мир устроен.

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

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

Я не ною, что мешает. И про эту настройку знаю.

Я про то, что определённого рода код писать с учётом такого рантайма на стандартной сишечке, мягко говоря, просто так не получится.

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

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

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

с чего это система вдруг что-то зануляет?

С того, что POSIX предписывает:

MAP_ANONYMOUS
       The mapping is not backed by any file; its contents are initialized to zero.

А так как malloc()/calloc() дёргает mmap() для больших размеров, то и зануляет.

Другой источник памяти это sbrk(), который тоже зануляет.

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

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

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

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

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

А ты мне про пользовательский процесс в вакууме не рассказывай. Вопрос ТС был о занулении памяти calloc() и эффектах на реальной системе, а значит неотрывно связан с конкретной реализацией, а не витает в вакууме как абстрактная машина, в терминах которой стандарт описывает поведение программы на C.

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

я тебе про конкретную систему Linux говорю. ничего система тебе не зануляет. calloc, если он есть, зануляет. это библиотечная функция, к системе никак не относится. и то не факт, что это работает быстрее обычного зануления после вызова malloc, потому что реализация не обязывает ни к чему.

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

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

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

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

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

память была на момент маллока, а потом кончилась

она должна была кончится для второго маллока, а не для первого

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

Выделите гиг анонимной памяти на машине с 2-мя гигами ОЗУ, сделайте 10 раз форк

наш бог умеет COW

и попытайтесь каждым процессом эту память записать. И где теперь ваш бог?

он сказал мне отключить оверкоммит

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

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

Вот пусть они и падают, а не на кого мемкиллер пошлёт.

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

выделение памяти в современных системах - более сложная схема,

И ты о нём ничего не знаешь.

более сложная схема, чем просто резервирование и обнуление.

Нет.

Тебе уже сказали, что вся память которую ты можешь по лучить от системы - занулённая. Это было сказано в конкретном контексте и твои попытки слиться на «я не юзаю glibc» и прочее - никого не волнуют, т.к. это всё за рамками контекста.

Кстати, нет ни одной libc альтернативой glibc по производительности. Как там сидится на говне, гений оптимизаций?

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

If the space cannot be allocated, a null pointer shall be returned.

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

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

Это у тебя ересь. Ты можешь своим правильным только подтереться т.к. реальное поведение описывает «непереносимая ересь».

If the space cannot be allocated, a null pointer shall be returned.

Тебе space allocated, не волнуйся. Только из этого space ничего не следует. Кто тебе сказал, что это память? Правильно, никто.

Поэтому работа полностью соответствует твоему описанию. Другое дело, что ты, как и многие тебе подобные - перепутал space и память. Такое бывает.

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

он сказал мне отключить оверкоммит

Опять эти глупые заявления от людей, которые не понимаю всей глупости своей заявлений. Это ничего тебе не даст. Никакой оверкоммит отключить нельзя. По определению.

И даже если ты его «отключишь», то это тебе ничего не даст по той причине, что считает оно vm в рамках процесса, а не системы. А это значит, что описанное тебе сработает в любом случае.

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

наш бог умеет COW

И как, ваш бог уже научился при помощи COW сделать из 2 ГБ ОЗУ — 10?

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

Ты споришь с царем. Все вы.

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

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

обнулить она её может, если это кусок системной памяти, и то в целях безопасности

Это именно что строго требуемое действие безопасности по отношению к анонимным страницам памяти. Как насчёт утечки приватного ключа или других данных, не подлежащих разглашению, другому пользователю через тупой цикл с mmap()-munmap()?

я тебе про конкретную систему Linux говорю. ничего система тебе не зануляет.

Сорцы ядра почитай. А хотя:

не хочу даже вникать.

Понятно.

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

И даже если ты его «отключишь», то это тебе ничего не даст по той причине, что считает оно vm в рамках процесса, а не системы. А это значит, что описанное тебе сработает в любом случае.

Читай: https://www.kernel.org/doc/Documentation/vm/overcommit-accounting

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

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

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

мы не ленивые, мы документацию читать умеем:

The calloc() function shall allocate unused space for an array of nelem elements each of whose size in bytes is elsize. The space shall be initialized to all bits 0.

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

там парой предложений выше написано:

The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object with a fundamental alignment requirement and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated).

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

Тебе space для object дали? Дали. Диапазон адресов корректный, с другими объектами не пересекается, имеет правильное выравнивание и т.п. В чем твоя претензия?

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

мне space нужен чтобы access object

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

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

Я кинул в ЖЖшку цитату царя и кусок кода.

Оказывается, даже мастистые программеры проверяли возвращаемое malloc'ом значение! И не парились, что памяти реально может и не быть...

Вот такие пироги. Никто не любит читать документацию.

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

Надо создать нытик-тему «почему я не могу перехватить SIGKILL».

надо? создай

space есть.

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

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

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

Оказывается, даже мастистые программеры проверяли возвращаемое malloc'ом значение!

А ты как хотел? Если ты исчерпаешь адресное пространство, malloc() вернёт ноль. Магии в компьютерах нет.

Deleted
()
Последнее исправление: Deleted (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.