Технотрек: Промышленное программирование. Занятие 03: Неубиваемый стек

Oct 05, 2016 02:26


(Копия блога на Технотреке)

Summary

Мы рассмотрели простейшую структуру данных - стек (буфер LIFO) и его реализацию в Си с точки зрения объектно-ориентированного программирования. Для этого мы применили логическую группировку данных (структуру, struct) и семейство функций (методов), связанных с ней. Типичными методами являются инициализация (конструкция, Stack_ctor), деинициализация (деструкция, или очистка, Stack_dtor), тихая верификация (Stack_OK) и отладочный дамп (Stack_dump). Первые две последних функции поддерживаются С++ как конструкторы и деструкторы; для последних двух нет явно поддерживаемых эквивалентов, но без них легко допустить ошибку даже в простой структуре данных и очень тяжело ее поймать. Также рассмотрели стратегии двойной проверки для динамической верификации объектов стека.

Домашнее задание


1. Реализуйте стек с внешним хранением данных в динамической памяти (более простой вариант задания - с внутренним хранением данных в самой структуре стека), его Си-эквиваленты конструктора, деструктора, тихого верификатора и дампа. Сделайте очень подробный и красивый дамп! (См. пример дампа здесь, на заднем плане.) Подумайте, как дамп может выводить имя переменной стека (в отладочном режиме компиляции).

2. Прочитайте, что такое юнит-тесты (готовьте вопросы к след. лекции) и реализуйте их для стека в достаточном количестве.

3. Попробуйте запортить стек, сделав намеренные ошибки в методах push() и рор(): переполнение и антипереполнение стека, смена знака счетчика стека, обнуление указателя на данные и т.п. Все ли эти ошибки являются критическими, говорящими об испорченных данных, или некоторые из них являются лишь некорректными действиями, примененными к правильно устроенному стеку? Разработайте стратегии реакции на разные виды ошибок в режимах компиляции Debug и Release (кстати, что что такое? См. про условную компиляцию), прочитайте про errno. Жду Ваших вопросов и обсуждения по этой задаче.

4. Попробуйте запортить стек внешним образом, за пределами его методов. Например, объявите до и после стековой переменной по массиву и позаходите за их границы, залезая в структуру стека и перезаписывая ее содержимое. (Обычно компилятор располагает переменные в памяти по порядку их объявления.) Как в этом случае детектировать такие ошибки и реагировать на них?

5*. Реализуйте юнит-тесты, намеренно создающие ошибочные ситуации и проверяющие реакцию системы верификации - это юнит-тесты к самим верификаторам.

На следующей лекции мы обсудим Ваши инженерные решения (готовьтесь! советую пообсуждать это друг с другом; в идеале часть лекции можно посвятить коротким выступлениям команд или менторских групп).

***

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

Удачи, и May the Source be with you! :)

Технотрек

Previous post Next post
Up