LINUX.ORG.RU

Почему надо проверять malloc на NULL

 , ,


1

3

Вообще выделение памяти проверять.

А вот потому что:

#include <stdio.h>
int main()
{
  unsigned char *a = NULL;
  int b = 0;
  unsigned long n = (unsigned long)&b;
 
  printf("b = %d, n = %lu\n",b,n);
  a[n]=1;
  printf("b = %d\n",b);
  return 0;
}

Запуск

$ gcc nullptr.c -o nullptr
$ ./nullptr 
b = 0, n = 140731726099148
b = 1

Запускалось в 64-битном (x86_64) Linux. Как видно, никаких сегфолтов и прочих ошибок. Конечно, адрес в районе 127 Тб в примере далеко за пределами доступного почти на всех компьютерах, но нет никаких гарантий, что на какой-то системе с каким-то компилятором и настройками среды значение не окажется более доступным. Могут быть и другие архитектуры (32-битные например), если запускать от root'а, то в начало может быть разрешена запись и там иметься память процесса. Или ещё какие-то варианты.

shdown, monk, liksys, Xenius - я думаю вам понравится. Пример сочинился по ходу чтения обсуждения Вышло издание 2,92 книги «Программирование: введение в профессию» А. В. Столярова (комментарий)

★★★★★

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

Просто расскажите в 2х словах что по вашему мнению при внутренних ошибках такого модуля должно происходить?

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

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

Тут еще важный вопрос: откуда у bugfixer-а уверенность что если если на цепочке сообщений (m1, m2, …, mN) он инициирует abort, то затем на повторении этой же цепочки после рестарта не произойдет тоже самое.

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

Еще была история, но связанная с другой ситуацией. В приложении было несколько активных объектов каждый из которых работал со своей пачкой внешних сервисов (т.е. конектился к ним и через долгоживущие соединения обенивался кучей информации). Каждый такой активный объект сохранял свое состояние в БД. Иногда связь с БД рвалась, у активного объекта переставали проходить обращения к БД. Самым простым решением мне тогда показалось инициировать рестарт всего приложения если у какого-то из активных объектов начинались проблемы с БД (т.к. сложно было переделать логику активного объекта, который мог бы какое-то время работать без коннекта в БД).

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

Но там получилось так, что если коннект к базе терялся, то с большой долей вероятности коннект терялся вскоре после рестарта. А потом еще раз. И так несколько раз, пока связь с серваком БД не восстанавливалась полностью.

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

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

Было некритично, но неприятно.

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

Тут еще важный вопрос: откуда у bugfixer-а уверенность что если если на цепочке сообщений (m1, m2, …, mN) он инициирует abort, то затем на повторении этой же цепочки после рестарта не произойдет тоже самое.

Его это в принципе устраивает:

Почему надо проверять malloc на NULL (комментарий)
Почему надо проверять malloc на NULL (комментарий)

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

единственная на весь тред ситуация, когда казалось-бы «malloc()==NULL» дозволяет откатить и продолжить, описана топик-стартером. Заметим, что не апологетами этих самых откатов.

процесс читает файл и строит что-то там в памяти. Например читает json и конструирует DOM. Ну и как вы тут корректно обработаете ошибку с malloc==NULL, да ещё и чтобы продолжить работу, «отрехнулась и пошла» ?

вы-ж на словах, собаку съели с мишн-критикал и проектируете с учётом сбоев/ошибок.

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

Его это в принципе устраивает

Я прекрасно понимаю о чем bugfixer говорит и во многом с ним согласен в ситуациях, когда у разработчика все окружение под контролем (но категорически не согласен с пассажем про «лапки»).

Однако, даже когда мы договорились, что нехватка памяти – это жесткий форс-мажор, при котором жизни нет от слова совсем, то abort при NULL из malloc-а будет нормально работать только при условиях, что нехватка памяти возникает не из-за нас самих.

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

Это вполне себе OK.

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

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

Поэтому даже когда для нас в принципе нормально прервать работу из-за NULL из malloc-а, могут быть неприятные моменты и циклы рестартов.

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

Я прекрасно понимаю о чем bugfixer говорит

Не могу этим похвастаться. Большая часть постов - это толчея воды в ступе и уход от вопросов.

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

abort при NULL из malloc-а будет нормально работать только при условиях, что нехватка памяти возникает не из-за нас самих.

Но вот если NULL возникает из-за проблем в нашем же коде.

Я, признаться, с точки зрения обработки результатов вызова malloc принципиальной разницы не вижу.

Она тут есть с организационной точки зрения: кто крайний из-за отказа в обслуживании - разработчик или эксплуатация?

Кроме того, есть ещё третий сценарий, мой любимый - когда отказ в обслуживании вызван входящими данными. Сделали мы некую логику, она успешно работает на 99,9% случаев, пока не приходит тот самый 0,1, где надо выделить вместо килобайта гигабайт.

В кровавом о таких сценариях как правило вообще не думают, пока не выстрелит.

Я бы сказал, что abortится на NULL от malloc’а можно, если разраб живёт в серверной, прикованный цепью к стойке, и готов по первому дампу кидаться править код.

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

Я, признаться, с точки зрения обработки результатов вызова malloc принципиальной разницы не вижу.

С точки зрения результатов обработки нет.

Есть с точки зрения простоты разработки. Одно дело писать софт под конкретные требования, которые будут обеспечиваться в рамках специального заповедника. Тогда можно исходить из того, что будет адекватный расчет объемов и мощностей, программа будет работать в условиях достатка памяти, поэтому можно сэкономить на разработке тем, что NULL из malloc – это всегда abort, и откаты в коде можно не писать и не тестировать.

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

Кроме того, есть ещё третий сценарий, мой любимый - когда отказ в обслуживании вызван входящими данными. Сделали мы некую логику, она успешно работает на 99,9% случаев, пока не приходит тот самый 0,1, где надо выделить вместо килобайта гигабайт.

Вот тут вы прям в корень зрите.

Я бы сказал, что abortится на NULL от malloc’а можно, если разраб живёт в серверной, прикованный цепью к стойке, и готов по первому дампу кидаться править код.

Не исключено, то у bugfixer-а так и есть ;)

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

Ну и как вы тут корректно обработаете ошибку с malloc==NULL, да ещё и чтобы продолжить работу, «отрехнулась и пошла» ?

Освободил частично построенный DOM и return ENOMEM. А если на COPY temp (data) FROM 'data.json' при большом data.json будет падать вся СУБД, это намного хуже.

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

В кровавом о таких сценариях как правило вообще не думают, пока не выстрелит.

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

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

банках

Это далеко не самый кровавый - всё ключевое ПО там от третьих сторон.

аэропортах

Там вообще на грани автоматики и тоже ПО от третьих сторон.

r--r--r--
()
Ответ на: комментарий от monk

Освободил частично построенный DOM и return ENOMEM. А если на COPY temp (data) FROM 'data.json' при большом data.json будет падать вся СУБД, это намного хуже.

Типичная «шутка» на испытаниях - data.json FIFO от бесконечного генератора. Хорошо если парсер не recusrive-descendand. И в стресс-тестах, во время «освобождаю недостроенный XXX Gb DOM на мильоны узов» прилетит сигнал от OOM киллера.

по хорошему до malloc()==NULL не доводят. Это-ж UB во все поля, не понятно кто сожрал память, сколько сожрал, осталось/нет. И вероятность что процесс прямо сейчас снаружи прибьют резко возрастает. То если уж такое случилось, то «падают».

В приведённом примере, чтобы не доводить до нехорошего - память считают, для мелочи свой аллокатор, malloc()`ом берут разумно большие блоками (пулами),

при выходе за собственный софт-лимит, отдают пулы. И в nginx и в apache.

и уходят в точку восстановления (до уровня изоляции ошибки). Теперь можно, ситуация recoverable, до критической ошибки недошли.

А чтобы до точки добираться,и не изобретать exception на Си, 'COPY temp (data) FROM 'data.json' скорее корутина/green-thread, тогда её проще отбрасывать. Или скрипт, байт-код управляемой машины, тоже вполне изолирует.

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

не готовы тратить существенное время/деньги ? тогда if (malloc()==NULL) abort()

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

во время «освобождаю недостроенный XXX Gb DOM на мильоны узов» прилетит сигнал от OOM киллера

kill -9 от идиота тоже может вообще любую секунду прилететь. Если нужна стабильная работа, OOM киллер выключают, а резервирование памяти при выдаче включают.

И там, где есть OOM киллер, он прибьёт программу намного раньше, чем malloc вернёт NULL.

не понятно кто сожрал память, сколько сожрал, осталось/нет

Почему не понятно? Понятно, что памяти на данный момент больше нет. Никакого UB в этой ситуации нет. Часто можно даже сообщить пользователю о нехватке и уйти в ожидание, пока появится. Примерно так: https://i.sstatic.net/PNRZN.png

В приведённом примере, чтобы не доводить до нехорошего - память считают, для мелочи свой аллокатор, malloc()`ом берут разумно большие блоками (пулами),

От ООМ киллера не спасает. Он же не при маллоке прибегает, а когда кто-то начал писать в последнюю свободную страницу. И даже убивает не этого кого-то, а кого попало. Поэтому даже если в твоей программе вообще нет malloc, она всё равно может быть внезапно убита.

А чтобы до точки добираться,и не изобретать exception на Си, ’COPY temp (data) FROM ‘data.json’ скорее корутина/green-thread, тогда её проще отбрасывать.

Так abort() прибьёт всё приложение, а не корутину.

не готовы тратить существенное время/деньги ? тогда if (malloc()==NULL) abort()

А почему не if (malloc()==NULL) return ENOMEM?

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

Примерно так:

картинка-то как раз выдана в ситуации до malloc=NULL. Софт (не будем показывать пальцем чей) сумел спрогнозировать потребности, оценить возможности и остановился ДО критической ошибки с неполучением памяти. Ему даже хватило ресурсов окошко нарисовать :-)

MKuznetsov ★★★★★
()

Стесняюсь спросить, а Вам зачем эти ритуалы с тайпкастингом на поинтеры понадобились?

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

программа будет работать в условиях достатка памяти, поэтому можно сэкономить на разработке тем, что NULL из malloc – это всегда abort, и откаты в коде можно не писать и не тестировать.

Именно так. Более того - я в принципе считаю что останавливающийся конвеер лучше чем тот что начинает отхаркивать в вас покорёженными заготовками.

Не исключено, то у bugfixer-а так и есть ;)

Масштаб катастрофы вы, вероятно, даже не представляете ;) Но я вас уверяю что при всей его саркастичности - от такой «цепи» товарищ тоже бы не отказался. В дальнейшие детали я бы предпочёл не углубляться.

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

от такой «цепи» товарищ тоже бы не отказался

Товарищ уже давно отказался от идей сидеть на цепи - несколько насиделся.

я вас уверяю

Возьмите себе за правило не говорить за других. Будете создавать у окружающих обманчивое впечатление взрослого человека.

r--r--r--
()
Ответ на: комментарий от MKuznetsov

картинка-то как раз выдана в ситуации до malloc=NULL.

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

Ещё можно вспомнить браузеры, которые при нехватке памяти закрывают одну вкладку,

СУБД, которые пишут в журнал

UTC ERROR:  out of memory
UTC DETAIL:  Failed on request of size 125.
UTC CONTEXT:  automatic analyze of table "xxx.public.delayed_jobs"
TopMemoryContext: 68688 total in 10 blocks; 4560 free (4 chunks); 64128 used

и завершают запрос, а не всю СУБД.

Ему даже хватило ресурсов окошко нарисовать :-)

Окошко нарисовано заранее, а делание окошка видимым malloc не вызывает.

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

Окошко нарисовано заранее,

Нет. Со стороны user32.dll и менеджера сессий / граф. подсистемы для модальных окон заранее аллоцированы ресурсы. Это позволяет вывести диалог, даже если процесс в предсмертном состоянии.

Само окошко не только не нарисовано, но даже не существует до ошибки.

r--r--r--
()
Ответ на: комментарий от monk

В момент. Он запросил достаточное количество памяти для отмены, получил NULL

сильно вряд-ли :-) когда дошло до того что «пора пополнить пул», посмотрел что есть, проверил собственные лимиты и выкинул окошко. Или вообще на этапе планирования - прикинул сколько надо, сколько могут дать и пожаловался.

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

Само окошко не только не нарисовано, но даже не существует до ошибки.

Уверен? Тут же нет динамических данных. Оно может быть заранее нарисовано (и часто так делают).

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

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

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

Оно может быть заранее нарисовано

Ты точно понимаешь смысл слова "нарисован"? "Нарисован" - это когда буфер с пикселями в видеопамяти.

(и часто так делают).

Так никогда не делают.

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

Так никогда не делают.

Почему? Я в своих графических почти всегда так делал. Типа

GtkWidget *error_dialog, *complete_dialog, ...;

int main()
{
   ...
   error_dialog = init_error_dialog();
   complete_dialog = init_complete_dialog();
   ...
   ...
   ...
   gtk_main();
}

int f()
{
   ...
   if (error) {
      set_error_message(error_dialog, ERR_MSG42);
      gtk_widget_show(error_dialog);
      return;
   }
   ...
}

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

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

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

До вызова gtk_widget_show(error_dialog); в видеопамяти нет ни одного пикселя от твоего диалога.

Это же быстрее,

Вообще без разницы. Машинерия на создание окон обычно копеечная.

r--r--r--
()
Ответ на: комментарий от bugfixer

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

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

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

Безусловно отличаются. Как ожидаемостью, так и возможностью последующей recovery.

Я запускаю веб-сервер. Он хочет открыть ключ для TLS, с диска. Ключа нет. Почему мне не надо делать abort()?

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

«malloc()==NULL» дозволяет откатить и продолжить

Вот ещё держи:

Пользователю показывают картинки, много, часто, случайно-разных, пользователь видит от C до 10*C картинок, это то кол-во картинок, которое должно быть единомоментно в памяти (x из [C,10*C]). Всего картинок N штук, это самое N огромно. Я пред-кеширую M картинок, то есть стараюсь держать кол-во загруженных в память, но ещё не показанных пользователю картинок ≤M. Итого держу в памяти ≤x+M+U картинок, где U — те, которые уже показаны, но я ещё не успел выгрузить или считаю, что они будут снова показаны ближайшее время и держу их в кэше. ЭВМ пользователя я не контролирую, кол-во доступной памяти для моей программы может меняться.

И вот, загружаю я очередную картинку. выделяю чанк памяти под ~10 типичных картинок. Системный аллокатор возвращает NULL.

ПредлОжите abort()?

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

Если хочешь сделать непадучую программу, то malloc-ом вообще нельзя пользоваться. Точнее один раз при старте, заховав памяти, сколько считаешь нужным, например, 1/3 ram и далее инициализировать её и работать только в пределах выделенного, сам распределяя под картинки сколько нужно. То есть со своим менеджментом памяти.

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

До вызова gtk_widget_show(error_dialog); в видеопамяти нет ни одного пикселя от твоего диалога.

«Нарисовать» и «отобразить нарисованное» — это всё-таки разные процессы.

Машинерия на создание окон обычно копеечная.

По-всякому бывает. Если там какая-нибудь табличка с GtkList, может быть и долго.

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

И запускать не на Линуксе. Или обеспечить, чтобы не было других процессов. Или хотя бы выключить ООМ киллера.

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

«Нарисовать» и «отобразить нарисованное» — это всё-таки разные процессы.

Да, если используется двойная или тройная буферизация. Поэтому я использовал термин "видеопамять", а не "буфер экрана". В твоём сообщении нет возражения на мой пост.

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

Точнее один раз при старте, заховав памяти, сколько считаешь нужным, например, 1/3 ram и далее инициализировать её и работать только в пределах выделенного,

Пара таких программ и уже третью не запустишь. Отличное решение :) Для сервера под какую-то фиксированную задачу, даже наверное и здорово.

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

И вот, загружаю я очередную картинку. выделяю чанк памяти под ~10 типичных картинок. Системный аллокатор возвращает NULL.

ПредлОжите abort()?

Возможно это единственное место в вашей программе с более-менее понятной стратегией recovery (почистить кеш и попытаться снова). Если кеш картинок единственный «тяжелый» потребитель памяти - возможно даже имеет смысл пытаться его чистить когда NULL прилетает в алокациях не имеющих непосредственного отношения к этому кешу. А так да - прямиком в какую-то форму abort().

ПыСы. Что если вы просто медленно течёте?

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

Возможно это единственное место в вашей программе с более-менее понятной стратегией recovery (почистить кеш и попытаться снова).

Спасибо, что признаёте здесь возможность неупасть.

А так да - прямиком в какую-то форму abort().

Не признаёте(((

ПыСы. Что если вы просто медленно течёте?

Я не теку, потому что кэш это единственное место, где делается malloc это кеш, а free не вызывается вообще: «выгрузка» картинок это уменьшение счетчика хранимых картинок в кеш-чанке. Все кеш-чанки переиспользуются (когда счетчик хранимых картинок == 0, offset = 0 и пошли использовать этот чанк как ново-созданный).

Если течёт какая-то либа, которую я не контролирую, то обработка NULL всё равно сокращает отношение числа падений к числу запусков.

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

Я не теку, потому что кэш это единственное место, где делается malloc это кеш

Если это соответствует действительности, то очевидно что нужно делать. Однако терзают меня смутные сомнения…

Если течёт какая-то либа, которую я не контролирую, то обработка NULL всё равно сокращает отношение числа падений к числу запусков.

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

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

ковылял из последних сил

… маскируя реальную и внешнюю по отношению к этому модулю проблему.

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

Встраивать излишний запас прочности тоже не всегда есть хорошо

Да я согласен.

можно найти им лучшее применение чем войны с ветряными мельницами.

Однозначно

BruteForce ★★★★
()

Как думается, в предоставленном примере как минимум однажды (потенциально минимум дважды) сделано UB:

unsigned char *a = NULL;
[...]
a[n]=1;

и потенциально в
unsigned long n = (unsigned long)&b;

https://cstd.eisie.net/c23.html#6.3.2.3p6

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

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

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

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

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

когда у тебя UB в коде — может произойтить что угодно. Любое поведение программы будет соответствовать стандарту C (как и C++).

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

В раст сделать побитовую запись в произвольный адрес памяти невозможно без ансейф.

«[memory.bytes.intro] The most basic unit of memory in Rust is a byte.»
https://doc.rust-lang.org/reference/memory-model.html#r-memory.bytes.intro

что, как думается, подразумевает принципиальную невозможность побитовой записи в память вообще (как и в C, C++).

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

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

Я выше привел еще один такой вариант и могу придумать еще с пяток разных. И все это будет типа безопасно, но не то. Не прямая запись, как в оригинале.

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

я говорил про «побитовую запись» таковая невозможна для велью-репрезентации. Минимально оперируемая сущность в памяти — это байт.

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

Я еще думал помню - исправлять не исправлять. Ай, думаю - похрен. И так все поймут о чем я.

LightDiver ★★★★★
()
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария