Opened 5 years ago
Closed 5 years ago
#203 closed ожидается проверка (задача сдана)
WW #3
Reported by: | Vavilov Mark | Owned by: | Sokolov Viacheslav |
---|---|---|---|
Component: | WW_intrusive_list | Version: | 2.0 |
Keywords: | Cc: |
Description
Change History (3)
comment:1 Changed 5 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
comment:2 Changed 5 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|---|
Version: | 1.0 → 2.0 |
comment:3 Changed 5 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
к сожалению, в финальной версии есть несколько проблем, в результате которых я могу поставить баллы только за стиль, но не корректность.
12 point *point = malloc(sizeof(point));
Угадайте, чему равен sizeof(point). вот чему
При добавлении первой вершины после аллокации prev и next могут быть заполнены мусором (не NULL). После добавления такой вершины в список текущим методом будет проблема.
Даже после исправления этих проблем получаю с address_sanitizer-ом
================================================================= ==24211==ERROR: AddressSanitizer: heap-use-after-free on address 0x603000000018 at pc 0x560e864681ee bp 0x7ffc3bbc1fb0 sp 0x7ffc3bbc1fa0 READ of size 8 at 0x603000000018 thread T0 #0 0x560e864681ed in show_all_points src/main.c:47 #1 0x560e86468841 in main src/main.c:101 #2 0x7f0a55f14b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96) #3 0x560e86467169 in _start (/home/nicesap/HSE/svn/vavilov.mark/lab_03/lab_03+0x3169) 0x603000000018 is located 8 bytes inside of 24-byte region [0x603000000010,0x603000000028) freed by thread T0 here: #0 0x7f0a570e37b8 in __interceptor_free (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xde7b8) #1 0x560e8646807f in remove_point src/main.c:31 #2 0x560e864687f3 in main src/main.c:96 #3 0x7f0a55f14b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96) previously allocated by thread T0 here: #0 0x7f0a570e3b50 in __interceptor_malloc (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xdeb50) #1 0x560e86467d82 in add_point src/main.c:12 #2 0x560e86468715 in main src/main.c:91 #3 0x7f0a55f14b96 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21b96) SUMMARY: AddressSanitizer: heap-use-after-free src/main.c:47 in show_all_points Shadow bytes around the buggy address: 0x0c067fff7fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0x0c067fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 =>0x0c067fff8000: fa fa fd[fd]fd fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8010: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 0x0c067fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa Shadow byte legend (one shadow byte represents 8 application bytes): Addressable: 00 Partially addressable: 01 02 03 04 05 06 07 Heap left redzone: fa Freed heap region: fd Stack left redzone: f1 Stack mid redzone: f2 Stack right redzone: f3 Stack after return: f5 Stack use after scope: f8 Global redzone: f9 Global init order: f6 Poisoned by user: f7 Container overflow: fc Array cookie: ac Intra object redzone: bb ASan internal: fe Left alloca redzone: ca Right alloca redzone: cb ==24211==ABORTING
на тесте
add 1 1 rm 1 1 len print exit
Note: See
TracTickets for help on using
tickets.
Смешаны пробелы и табуляции.
Не хватает зависимостей .o файлов от .h файлов.
Расписал https://wiki.compscicenter.ru/index.php/C%2B%2B_1MIT_осень_1_2019#.D0.A2.D1.80.D0.B5.D0.B1.D0.BE.D0.B2.D0.B0.D0.BD.D0.B8.D1.8F_.D0.BA.D0.BE.D1.80.D1.80.D0.B5.D0.BA.D1.82.D0.BD.D0.BE.D1.81.D1.82.D0.B8.2C_.D0.BF.D1.80.D0.B5.D0.B4.D1.8A.D1.8F.D0.B2.D0.BB.D1.8F.D0.B5.D0.BC.D1.8B.D0.B5_.D0.BA_.D1.80.D0.B0.D0.B1.D0.BE.D1.82.D0.B0.D0.BC и, в частности, не хватает:
malloc не обязан заполнить память нулями, в частности, указатели у head будут не NULL при инициализации списка
malloc в add_point: хорошо, что есть проверка возвращаемого указателя, но поведение программы сейчас получается неудачное: точку попросили добавить, не получилось, работаем дальше, при этом не выполнили контракт. По сути маскируется проблемная ситуация. Вариант исправления: вместо void add_point сделать int add_point, возвращать код -1 (это не самая удачная идея в общем случае, но так принято в языке Си; подробнее об этом еще поговорим на парах) и из int main тоже возвращать ненулевой код.
Читаемость: либо везде пустая строкая перед else, либо нигде (на мой вкус лучше нигде - пустыми строками удобно отделять независимые или последовательные блоки, if-else же монолитная конструкция)
Сейчас в программе есть формальная ошибка: strcmp работает с 0-терминироваными строками, а после scanf "%6s" в конце не будет нулевого символа; его не будет еще и из-за malloc.
Обычно фиктивная вершина заводится, чтобы не приходилось разбирать случаи в add_node , remove_node.