Pull to refresh
  • by relevance
  • by date
  • by rating

10 лет практики. Часть 2: ресурсы

C++
Здравствуйте. Я планировал написать большую статью об управлении ресурсами в С++.
Но на практике, тема эта такая сложная и многогранная, что я хочу остановиться на определённой методике, которой пользуюсь сам. Данная методика не является спасением на все случаи жизни, но экономит много времени и нервов при работе с объектами. При этом, не является широко известной.
Читать дальше →
Total votes 30: ↑22 and ↓8 +14
Views3K
Comments 40

GC в C++: преодоление соблазна

C++ООP
Недавно появилась заметка о простой и эффективной «ручной» сборке мусора в С++. Вполне допускаю, что локальная сборка мусора внутри какого-то сложного класса (где идёт активная низкоуровневая работа с указателями) может быть оправдана. Но в масштабах большой программы, существует более надёжный и простой метод избавления от утечек памяти. Не претендуя на «метод на все случаи жизни», очень надеюсь, что он сделает проще жизнь хотя бы некоторым из читателей.

Суть метода предельно проста: если каждый объект является переменной какой-либо области видимости или простым («стековым») членом другого объекта, то даже при аварийном закрытии программы от необработанного исключения, всегда будет происходить корректная очистка. Задача заключается в том, чтобы свести всё многообразие динамических сценариев к этой схеме.
Вот отсюда поподробнее...
Total votes 33: ↑28 and ↓5 +23
Views8.2K
Comments 39

Меченые указатели, или как уместить объект в одном инте

High performanceObjective C
Если вы когда-нибудь писали приложение на Objective-C, вы должны быть знакомы с классом NSNumber — оберткой, превращающей число в объект. Классический пример использования — это создание числового массива, заполненного объектами вида [NSNumber numberWithInt:someIntValue];.

Казалось бы, зачем создавать целый объект, выделять под него память, потом ее чистить, если нам нужен обычный маленький int? В Apple тоже так подумали, и потому NSNumber — это зачастую совсем не объект, и за указателем на него скрывается… пустота.

Если вам интересно, как же так получается, и при чем тут меченые указатели — добро пожаловать под кат!
Читать дальше →
Total votes 30: ↑25 and ↓5 +20
Views8.1K
Comments 20

Что не так с ссылками в С++

C++

Disclaimer: На данный момент я не располагаю достаточным опытом работы с С++11, поэтому все рассуждения следует рассматривать исключительно в контексте С++03, однако буду рад обсудить в комментариях взаимодействие нововведений С++ с рассмотренными в статье проблемами.

Ссылки в C++ появились чтобы удовлетворить синтаксические потребности механизма перегрузки операторов. В чистом С нет ссылочных типов, вместо этого есть понятие lvalue, которое описывается размытой формулировкой «то, что может стоять слева от оператора присваивания».

// Чистый C
int a;
int foo(int);
a = 7; // тип a - int
5 = 7; // и тип 5 - int
foo(42) = 7; // и тип foo(42) - тоже int 

В этом маленьком примере три выражения: переменная a, литерал «5» и вызов функции foo(42) — имеют одинаковый тип — int, но только переменная является lvalue и может стоять слева от оператора присваивания.

С точки зрения С программиста, выражение «foo(42) = 7;» лишено здравого смысла и не должно компилироваться, однако с появлением перегрузки операторов, возникла потребность именно в таких выражениях.

Читать дальше →
Total votes 28: ↑18 and ↓10 +8
Views30.7K
Comments 24

Заземлённые указатели

PVS-Studio corporate blogWebsite developmentC++
pointres, gnd

Не так давно, один из сотрудников покинул наш коллектив и присоединился к компании, занимающийся разработкой программного обеспечения, связанного с встраиваемыми системами. Ничего особенного в этом нет, всегда и везде, кто-то уходит, а кто-то приходит. Всё зависит от количества плюшек, удобства и предпочтений. Интересно другое. Человек искренне переживает за состояние кода на новом месте работы, что в результате и вылилось в эту совместную статью. Тяжело, «просто программировать», когда знаешь, что такое статический анализ кода.
Читать дальше →
Total votes 112: ↑94 and ↓18 +76
Views50.9K
Comments 140

C#: как «выстрелить себе в ногу»

Perfect code.NETC++C#Development for Windows
Рассмотрим, как можно «выстрелить себе в ногу» на C# (и в целом в .NET).
Оказывается, такое можно сделать не только на C++.

Ниже представлен код, «играющийся» с типом bool (System.Boolean) и выводящий на экран 20 строк True или False.
Для первых десяти строк поведение детерминировано только для первой строки, а поведение для 2-10 строк зависит от реализации компилятора.

Код вполне самодокументированный, поэтому добавлю только, что на подобное поведение вполне можно наткнуться при вызове неуправляемых функций через P/Invoke, в случае их некорректного использования (на эту тему будет продолжение).
Читать дальше →
Total votes 28: ↑11 and ↓17 -6
Views15.4K
Comments 7

C#: как не «выстрелить себе в ногу»

Perfect code.NETC++C#Development for Windows
Сегодня мы рассмотрим более детально, как стало возможным «выстрелить себе в ногу» на C#, а также в целом на .NET, при работе с логическими значениями, в каких практических кейсах это может произойти, и как этого не допустить.

Какие же строки выводятся на экран этим консольным приложением?
Запустив приложение, предварительно собрав его в среде Visual Studio Community 2013, получим следующий результат:

Unsafe Mode
01: b1        : True
02: b2        : True
03:  b1 ==  b2: False
04: !b1 == !b2: True
05: b1 && b2  : True
06: b1 &  b2  : True
07: b1 ^  b2  : True
08: b1 && b3  : True
09: b1 &  b3  : False
10: b1 ^  b3  : True

Safe Mode
11: b1        : True
12: b2        : True
13:  b1 ==  b2: True
14: !b1 == !b2: True
15: b1 && b2  : True
16: b1 &  b2  : True
17: b1 ^  b2  : False
18: b1 && b3  : True
19: b1 &  b3  : True
20: b1 ^  b3  : False

Исходя из допущения, что в каждой из логических переменных b1, b2, b3 находится либо «истинное» значение, либо значение, отличное от «ложного» (а, значит, тоже «истинное»? — ведь это булевы переменные?), возникают несколько вопросов:
  1. Почему в блоках Unsafe и Safe Mode разные результат в позициях 03 и 13, 07 и 17, 09 и 19, 10 и 20 соответственно?
    (а почему тогда значения в других соответствующих друг другу позициях в блоках Unsafe и Safe совпадают?)
  2. Почему внутри блока Unsafe результаты в позициях 05 и 06 одинаковы, а в 08 и 09 — разные?
    И почему результаты в 08 и 09 разные?

Попробуем разобраться:
Читать дальше →
Total votes 22: ↑8 and ↓14 -6
Views4.3K
Comments 10

Объекты нулевого размера

ProgrammingC
Translation
В чём разница между следующими парами длин и указателей?

size_t len1 = 0;
char *ptr1 = NULL;

size_t len2 = 0;
char *ptr2 = malloc(0);

size_t len3 = 0;
char *ptr3 = (char *)malloc(4096) + 4096;

size_t len4 = 0;
char ptr4[0];

size_t len5 = 0;
char ptr5[];


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

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

malloc(0)


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

Возврат NULL приводит к возможности возникновения интересного бага. Часто возврат NULL из malloc расценивается как ошибка.
Читать дальше →
Total votes 33: ↑29 and ↓4 +25
Views28.3K
Comments 14

Unsafe в Swift

Development for iOSSwift
Создатели современных языков программирования всеми силами пытаются увести программистов от прямой работы с указателями и памятью, либо вообще не включая в язык подобные возможности (например, Java) либо маркируя их страшными словами unsafe (C#). Пишущим на swift повезло, этот язык попал во вторую категорию, и хотя это не рекомендуется, а в документации встречаются предупреждения о возможных утечках памяти и прочих страшилках возможность такая есть!

В этой статья я хотел бы рассмотреть работу с указателями в swift, а так же порассуждать для чего это вообще может понадобиться.
Читать дальше →
Total votes 12: ↑10 and ↓2 +8
Views11.4K
Comments 15

Указатели на методы классов в C++

C++
Привет, интернет.

Решил написать статью об указателях на методы классов. Недавно мне пришлось столкнуться с тем, как они работают изнутри, когда писал некоторые вещи ориентированные под компилятор. Эти указатели работают не совсем как обычные указатели, не имеют возможности быть приведенными в void, и часто имеют размер больше 8 байт. Информации на эту тему в интернете я нашел относительно немного, потому решил разобраться сам.
Читать дальше →
Total votes 13: ↑13 and ↓0 +13
Views13.8K
Comments 39

Как проверить, находится ли значение указателя в заданной области памяти

PVS-Studio corporate blogC++System ProgrammingC
Translation
Пусть у нас есть регион/область памяти, заданный с помощью двух переменных, например:

byte* regionStart;
size_t regionSize;

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

if (p >= regionStart && p < regionStart + regionSize)

Но гарантирует ли стандарт ожидаемое поведение этого кода?
Читать дальше →
Total votes 40: ↑37 and ↓3 +34
Views12.1K
Comments 16

Указатели C как лингвистический парадокс

C++C
Недавно один знакомый, которого я знаю через совсем не программистские круги, попросил помочь ему с лабораторной по C++. В коде было примерно следующее:

void do_something(MyObj *input[], int count)
{
    MyObj **copy = new MyObj*[count];
    for (int i = 0; i < count; ++i)
        *copy[i] = *input[i];
    ...
}

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

Лет десять назад на одном форуме была загадана детская, вроде, загадка:
Для чего еду обеда
Людоедоедоеда
Пригласила на обед
Людоедоедовед?
Я хочу показать, что эта загадка имеет самое прямое отношение к C/C++, поскольку тема указателей легко может быть разобрана по аналогии.
Читать дальше →
Total votes 65: ↑56 and ↓9 +47
Views30.6K
Comments 244

Указатели в C абстрактнее, чем может показаться

PVS-Studio corporate blogC
Translation
Указатель ссылается на ячейку памяти, а разыменовать указатель — значит считать значение указываемой ячейки. Значением самого указателя является адрес ячейки памяти. Стандарт языка C не оговаривает форму представления адресов памяти. Это очень важное замечание, поскольку разные архитектуры могут использовать разные модели адресации. Большинство современных архитектур использует линейное адресное пространство или аналогичное ему. Однако даже этот вопрос не оговаривается строго, поскольку адреса могут быть физическими или виртуальными. В некоторых архитектурах используется и вовсе нечисловое представление. Так, Symbolics Lisp Machine оперирует кортежами вида (object, offset) в качестве адресов.
Читать дальше →
Total votes 64: ↑61 and ↓3 +58
Views26.6K
Comments 98

Самый полный русскоязычный перевод Гарвардского курса по программированию CS50 2015, бесплатно на YouTube

Programming
Sandbox
В этой статье я хочу немного рассказать о самом лучшем в мире курсе по программированию.

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

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

image
Читать дальше →
Total votes 19: ↑18 and ↓1 +17
Views50K
Comments 27

Указатели сложны, или Что хранится в байте?

ProgrammingC++System ProgrammingRust
Translation

Привет, Хабр! Представляю вашему вниманию перевод статьи "Pointers Are Complicated, or: What's in a Byte?" авторства Ralf Jung.


Этим летом я снова работаю над Rust фуллтайм, и я снова буду работать (помимо прочих вещей) над "моделью памяти" для Rust/MIR. Однако, прежде чем я заговорю о своих идеях, я наконец должен развеять миф, что "указатели просты: они являются просто числами". Обе части этого утверждения ошибочны, по крайней мере в языках с небезопасными фичами, таких как Rust или C: указатели нельзя назвать ни простыми, ни (обычными) числами.


Я бы также хотел обсудить часть модели памяти, которую необходимо затронуть, прежде чем мы можем говорить о более сложных частях: в какой форме данные хранятся в памяти? Память состоит из байтов, минимальных адресуемых единиц и наименьших элементов, к которым можно получить доступ (по крайней мере на большинстве платформ), но каковы возможные значения байта? Опять же, оказывается, что "это просто 8-битное число" не подходит в качестве ответа.

Читать дальше →
Total votes 40: ↑38 and ↓2 +36
Views14.8K
Comments 37

Создаем на C++ выразительные умные указатели для удаленной памяти

Издательский дом «Питер» corporate blogProgramming.NETC++Algorithms
Translation
Привет, Хабр!

Сегодня мы публикуем перевод интересного исследования о работе с памятью и указателями в C++. Материал немного академический, но явно будет небезынтересен читателям книг Галовица и Уильямса.

Следите за рекламой!
Читать дальше →
Total votes 22: ↑22 and ↓0 +22
Views9.1K
Comments 1

Внутренности Go: оборачиваем переменные цикла в замыкании

Badoo corporate blogHigh performanceProgrammingAssemblerGo
Translation


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


А еще я хотел бы пригласить вас на Golang Conf 2019, которая пройдет 7 октября в Москве. Я член программного комитета конференции, и мы с коллегами выбрали много не менее хардкорных и очень, очень интересных докладов. То, что я люблю!


Под катом передаю слово автору.

Читать дальше →
Total votes 73: ↑72 and ↓1 +71
Views11.7K
Comments 8

Структуры данных для программистов игр: bulk data

ProgrammingClient optimizationC++Game developmentC
Translation
image

Любому программисту будет полезно понимание различных структур данных и способов анализа их производительности. Но на практике мне ни разу не пригождались АВЛ-деревья, красно-чёрные деревья, префиксные деревья, списки с пропусками, и т.д. Некоторые структуры данных я использую только для одного конкретного алгоритма и ни для чего больше (например, кучи для реализации очереди с приоритетом в алгоритме поиска пути A*).

В повседневной работе я обычно обхожусь на удивление малым количеством структур данных. Чаще всего мне пригождаются:

  • Общие массивы данных (Bulk data) — способ эффективного хранения большого количества объектов.
  • Слабые ссылки (Weak reference) (или дескрипторы (handle)) — способ обращения к объектам в bulk data без сбоев программы в случае, если объект удалён.
  • Индексы — способ быстрого доступа к отдельным подмножествам в bulk data.
  • Массивы массивов — способ хранения объектов bulk data с динамическими размерами.

Я посвящу несколько статей тому, как я обычно реализую все эти структуры. Давайте начнём с простейшей и самой полезной — bulk data.
Читать дальше →
Total votes 28: ↑28 and ↓0 +28
Views13.9K
Comments 14

Что нового я узнал о компьютере, когда решил написать Chrome Dino на C

Abnormal programmingAlgorithmsC
Sandbox


Немного о проекте


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

.

typedef struct Barrier {
    int width, height;
    int *picture;
    int x0, y0;
} Barrier;

Barrier* new_Barrier() {
  Barrier* barrier = NULL;
  barrier = malloc(sizeof(Barrier));

  return barrier;
}

Для удобства работы с графикой изображения хранятся в виде матрицы со
значениями [0, 1, 2, 3], это решение подтолкнуло на написание этой
статьи.
0 — прозрачный,
1 — синий,
2 — черный,
3 — серый.



Читать дальше →
Total votes 19: ↑4 and ↓15 -11
Views4.1K
Comments 26

Связные списки, трюки с указателями и хороший вкус

Programming
Translation
В интервью на TED 2016 (14:10) Линус Торвальдс рассказывает о хорошем стиле программирования. В качестве примера приводит два варианта удаления элементов из односвязных списков (см. ниже). В первом варианте есть специальный случай, а в другом — нет. Линус предпочитает второй.

Его комментарий:

[...] Не надо размышлять, почему здесь нет оператора if. Важно посмотреть на задачу с другой стороны и переписать её так, чтобы особый случай исчез и стал обычным случаем, и это хороший код. — Л. Торвальдс

В качестве примера Линус показывает достаточно простой псевдокод в стиле Си. Но не даёт концептуального объяснения. Поэтому не сразу понятно, как работает косвенный указатель.
Читать дальше →
Total votes 35: ↑35 and ↓0 +35
Views18.1K
Comments 66