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 Sokolov Viacheslav

Type: ожидается проверкаожидаются исправления

Смешаны пробелы и табуляции.

Не хватает зависимостей .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 и, в частности, не хватает:

  • проверок ненулевых указателей
  • желательно в функциях add_node / remove_node проверять, что вершины отсуствует / присутствует, для чего удобно сделать вспомогательный метод
  • удобнее считать по ходу программы, что list уже инициализирован (чать контракта функций)

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.

comment:2 Changed 5 years ago by Vavilov Mark

Type: ожидаются исправленияожидается проверка
Version: 1.02.0

comment:3 Changed 5 years ago by Sokolov Viacheslav

Resolution: задача сдана
Status: assignedclosed

к сожалению, в финальной версии есть несколько проблем, в результате которых я могу поставить баллы только за стиль, но не корректность.

 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.