Opened 4 years ago
Closed 4 years ago
#683 closed ожидается проверка (задача сдана)
WW #11
Reported by: | Kreslavski Kirill | Owned by: | Артур Гулецкий (huletski) |
---|---|---|---|
Component: | WW cpp_io | Version: | |
Keywords: | Cc: |
Description
Я написал что-то относительно разумное, но оно пока не особо работает. Ошибок при работе с памятью вроде пока нет, но работу с файлами я ещё не проверял. Я видимо как-то не правильно написал оператор для вывода EmployeeArray?, поэтому у меня сейчас выводятся указатели на элементы, а не выводятся они сами.
Пофикшу всё при первой же возможности, но не раньше воскресенья.
Change History (5)
comment:1 Changed 4 years ago by
Summary: | WW cpp_io → WW #11 |
---|
comment:2 Changed 4 years ago by
Type: | ожидается проверка → ожидаются исправления |
---|
comment:3 Changed 4 years ago by
Type: | ожидаются исправления → ожидается проверка |
---|
Приложив неимоверные моральные усилия и переписав код раз 5 я всё-таки смог добиться полной работоспособности написанного. Причём оно даже работает корректно, не выдаёт ошибок в валгринде и выглядит приличнее чем предыдущая версия.
comment:4 Changed 4 years ago by
Я таки смог найти баг, из-за которого ловил segmentation fault. Там был цикл, который работал до _employee.size() + added_amount . А внутри этого цикла я добавлял элементы в вектор пушбэкая, тем самым динамически пересчитывался _employee.size() и я пытался считать что-то лишний раз, а считывать было неоткуда. Сейчас я залил в svn нормальную версию, которая работает и имеет одну точку принятия решения. failbit пока не понял как ставить, может быть допилю чуть позже (завтра или сегодня ночью)
comment:5 Changed 4 years ago by
Resolution: | → задача сдана |
---|---|
Status: | assigned → closed |
На примере из условия решение неверно работает с памятью, неверно записывается список сотрудников -> -2.5
{lab_11}[2016]$ pwd && svn up && svn status /home/hfx/dvl/cpp19/kreslavskiy.kirill/lab_11 Updating '.': At revision 2788. {lab_11}[2017]$ make mkdir -p obj g++ -O2 -Wall -Werror -std=c++11 -Iinclude -g -c -MMD -o obj/bin_manip.o src/bin_manip.cpp g++ -O2 -Wall -Werror -std=c++11 -Iinclude -g -c -MMD -o obj/main.o src/main.cpp g++ -O2 -Wall -Werror -std=c++11 -Iinclude -g -c -MMD -o obj/employees.o src/employees.cpp g++ obj/bin_manip.o obj/main.o obj/employees.o -o lab_11 {lab_11}[2018]$ valgrind ./lab_11 ==3843== Memcheck, a memory error detector ==3843== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. ==3843== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info ==3843== Command: ./lab_11 ==3843== add 2 Joe 100 20 300 add 1 Billy 1000 1 list 1. Sales Manager Name: Joe Base Salary: 100 Sold items: 20 Item price: 300 2. Developer Name: Billy Base Salary: 1000 Has bonus: + == Total salary: 2160 save example.edb load example.edb list 1. Sales Manager Name: Joe Base Salary: 100 Sold items: 20 Item price: 300 2. Developer Name: Billy Base Salary: 1000 Has bonus: + 3. Sales Manager Name: Joe Base Salary: 100 Sold items: 20 Item price: 300 4. Developer Name: Billy Base Salary: 1000 Has bonus: + == Total salary: 4320 save merged.edb exit ==3843== ==3843== HEAP SUMMARY: ==3843== in use at exit: 73,384 bytes in 15 blocks ==3843== total heap usage: 25 allocs, 10 frees, 101,688 bytes allocated ==3843== ==3843== LEAK SUMMARY: ==3843== definitely lost: 104 bytes in 4 blocks ==3843== indirectly lost: 576 bytes in 10 blocks ==3843== possibly lost: 0 bytes in 0 blocks ==3843== still reachable: 72,704 bytes in 1 blocks ==3843== suppressed: 0 bytes in 0 blocks ==3843== Rerun with --leak-check=full to see details of leaked memory ==3843== ==3843== For counts of detected and suppressed errors, rerun with: -v ==3843== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) {lab_11}[2019]$ hexdump -C merged.edb 00000000 04 00 00 00 02 00 00 00 4a 6f 65 00 64 00 00 00 |........Joe.d...| 00000010 14 00 00 00 2c 01 00 00 01 00 00 00 42 69 6c 6c |....,.......Bill| 00000020 79 00 e8 03 00 00 31 02 00 00 00 4a 6f 65 00 64 |y.....1....Joe.d| 00000030 00 00 00 14 00 00 00 2c 01 00 00 01 00 00 00 42 |.......,.......B| 00000040 69 6c 6c 79 00 e8 03 00 00 31 |illy.....1| 0000004a
По коду:
- нарушено rule of 3 для классов employees.h (copy ctor, op=, сгенерированные компилятором, работают неверно) -> -0.5;
- main.cpp:3. можно было хранить на стеке; выделенная память не освобождается;
- bin_manip.cpp:19, 43. отсутствует обработка ошибок (установка failbit) в коде считывания данных (bool - если считалось значение отличное от 0 и 1, c-string - не был найден нуль-терминатор -> -1;
- bin_manip.cpp:35. можно было записать std::strlen + 1 символов за один вызов write;
- employees.cpp:38. std::strncpy + std::string::c_str вместо поэлементного копирования;
+ часть замечаний из предыдущего комментария.
За мелкие замечания совокупно -0.75.
Баллы: 5.25.
Да как-то вообще не работает (даже
exit
):Похоже, проблема возникает, если вводить данные о SalesManager?'e.
Перед следующей попыткой протестируйте решение на данных из условия.
Так как решение слишком недоделано, код просмотрю по диагонали.
Замечания:
Misc
Employee *e = ...; stream << *e;
;op<<(std::ostream& os, const Employee &e)
вызываетe.print(os)
);main.cpp
35: считывайте в std::string изпользуя op>>; перемнные лучше объявлять рядом с местом первого использования;
40: loop-and-a-half. Можно переписать (чтобы убрать дублирование чтения) так:
54: этот код можно вынести в перегрузку op>> для
EmployeesArray
(бинарные ввод);bin_manip.cpp
7: что такое 4? если программа запущена на big-endian платформе порядок байтов будет записан неверно -> нужно писать байты инта по одному, чтобы гарантировать порядок;
17: можно не проверять, если поток fail вызов read проигнорируется. Кроме того, не стоит печатать сообщения, если они не отладочные: в манипуляторе (очень базовый, общий код) ошибку лучше обозначить (см. след. пункт) установкой бита состояния потока, а ее обработкой (игнорирование, печать сообщения, whatever) пусть занимается более высокоуровневый код;
50: можно добавить блок else, который устанавливает failbit; в op>> для read_c_str тоже не хватает установки failbit'ов, если формат отличен от ожидаемого;
employees.cpp
1, 2: cstring, cstdio
9: используйте списки инициализации;
27: используйте написанный манипулятор для чтения c-string;
36: strncpy;
44: strncpy(_name, s_tmp.c_str(), ...); напомню, что измененное условие позволяет хранить имена в std::string;
62, 63:
os << (_has_bonus ? '+' : '-') << std::endl
выглядит лаконичнее;149: дублирование кода определения типа и создания объекта по числовому коду (похожий код в main.cpp). Почему это особенно плохо в контексте лабораторной обсудили на практике;
Баллы: 1.5 (что-то похожее все-таки реализовано), доделывайте.
Еще 7 дней, по условию продления дедлайна. Обязательно перепроверьте решение на примере из условия перед посылкой.
Обратите внимание, что однотипные повторяющиеся замечания я не писал.