May 22nd, 2020

Даты круглые и не совсем круглые

Смотрим на календарь, а там 22 мая...

1742 год. Отряд из состава Великой Северной экспедиции под началом штурмана Семена Челюскина достиг самой северной оконечности России и Евразии - мыса, позднее названного именем Челюскина.
1769 год. В Москве был отлит большой колокол для курантов Спасской башни Кремля.
1785 год. В Москве состоялась закладка Дома Пашкова, здания в котором ныне расположена Российская государственная библиотека.
1813 год. Родился Рихард Вагнер (Wilhelm Richard Wagner), немецкий композитор.
1856 год. Покупкой нескольких картин меценат П. М. Третьяков положил начало Третьяковской галереи.
1859 год. Родился Артур Конан Дойль (Sir Arthur Ignatius Conan Doyle).
1911 год. Русским физиком Б. Л. Розингом был впервые продемонстрированы на экране электронно-лучевой трубки изображения геометрических фигур, что является прообразом современного телевидения.
1913 год. Родился Никита Владимирович Богословский, советский композитор.
1914 год. Родился Николай Фёдорович Макаров, советский конструктор стрелкового оружия.
1940 год. Учреждена золотая медаль "Серп и молот", вручавшаяся Героям Социалистического труда вместе с орденом Ленина.
1973 год. Робертом Меткалфом (Robert Metcalfe) подана докладная записка, содержащая описание протокола Ethernet.
1990 год. Вышла программная оболочка Windows 3.0.

Errare humanum est

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

double pData = new double [size];

Здесь size - размер массива. И вот тут-то и закралась ошибка. Вместо квадратных скобок я по ошибке написал круглые, то есть:

double pData = new double (size);

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

Дальнейшее выполнение программы зависит исключительно от везения программиста. Чисто теоретически, она может даже успешно выполняться. Особенно, если size мало. Гарантированно программу завалит команда освобождения памяти. Для освобождения памяти под одну переменную используется код:

delete pData;

А для освобождения памяти, распределенной под массив, необходимо использовать код:

delete [] pData;

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

Так что будьте внимательнее к мелочам.

Битва на Неве 2019. Второй день. Часть шесть.

Итак, прекрасные дамы свои состязания закончили (еще одно состязание - подъем с земли платка копьем я не фотографировал). Самое время сделать паузу и полюбоваться... на кого?

На прекрасных дам конечно!

Collapse )
Продолжение следует...