Как стать автором
Обновить

Комментарии 12

Начнем с динамической памяти.

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

В С есть максимальная свобода и контроль над своим кодом

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

Указатели на функции, типа-конструкторы/деструкторы и т.п. - не катит, потому что они не вызываются автоматически.

В любом учебнике, отдельно что потокам, что управлению памятью больше информации даётся. Тут всё очень поверхностно, чисто для рекламы курсов. Ещё и RAII зачем-то натягивается на си. Стоит объяснять людям, что не любой ресурс надо освобождать. Если программа запускается, выполняет одну задачу и завершается, ничего освобождать не нужно, ОС всё сделает за вас. Если программа аллоцирует ресурсы, а потом работает с ними в цикле (и в цикле никакие ресурсы не выделяются), то тоже ничего освобождать не нужно. Для управления памятью можно использовать не стандартный malloc, а arena allocator, да не всегда, но когда можно, жизнь он упрощает, ещё и работает быстрее, чем malloc. Потому что не нужно следить за жизнью 1000 ресурсов, потому что можно одним вызовом free освободить сразу всю 1000. Иногда можно использовать scratch arena (не знаю, как на русский перевести), там вообще можно ничего не освобождать. Передал в функцию копию аллокатора (не ссылку), функция что-то там повыделяла, но менялась при этом только копия аллокатора, а значит после завершения функции, вся память, ею выделенная считается доступной. Надо про это рассказывать, а не про то, как натягивать сову RAII на глобус Си.

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

numbers = realloc(numbers, sizeof(int) * 20);

if (numbers == NULL) {

// обработка ошибки выделения памяти

}

Тут потенциальная утечка памяти в ветки обработки ошибки из-за потери оригинального значения numbers.

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

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

А давайте вы в OTUS не будете заниматься SMM-спамом? Тем более, что вы, судя по комментариям настоящих специалистов, читающих ваши маркетинговые обязаловки, не очень разбираетесь в вопросах, о которых пытаетесь писать. И без вас шума много. Сконцентрируйтесь на своём основном занятии.

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

Очень поверхностно.

Например, для realloc не указано будет ли дополнительная память инициализирована нулями или нет, допущена утечка памяти в примере кода обработки ошибок.

Можно использовать фичи из C++ (что?)

Так а какие фичи из с++ внезапно оказались в с? RAII так и не завезли, с инциализаторами проблема также не решена. Кликбейтнули подзаголовок и не солоно хлебавши перешли сразу к фабричным функциям. Что?

Однако попробуем адаптировать RAII для C

То чувство, когда ожидаешь увидеть практическое применение __attrubute(( __cleanup ... и прочего, а по факту просто пишут - а давайте напишем функцию, что бы удалять поля структуры...

попробуем адаптировать RAII для C

IntArray_create и IntArray_destroy играют роли конструктора и деструктора.

Это все те же обычные функции, которые все так же нужно не забывать вызывать в нужных местах руками. Сделали инстанс IntArray где-то вне IntArray_create - рискуете получить невалидный объект. Не вызвали вовремя IntArray_destroy потеряв указатель - ресурс утек. RAII нужен как раз затем, чтобы такого не происходило, но его тут нет.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий