Opened 4 years ago

Closed 4 years ago

#560 closed ожидается проверка (задача сдана)

WW #9

Reported by: Vladislav Nosivskoy Owned by: Sokolov Viacheslav
Component: WW shared_ptr Version: 1.0
Keywords: Cc:

Description


Change History (1)

comment:1 Changed 4 years ago by Sokolov Viacheslav

Resolution: задача сдана
Status: assignedclosed
╰─>$ make
mkdir -p bin
g++ -O2 -Werror -Wall -Wno-self-assign -std=c++11 -Iinclude -c -MMD -o bin/matrix.o src/matrix.cpp
g++ -O2 -Werror -Wall -Wno-self-assign -std=c++11 -Iinclude -c -MMD -o bin/shared_ptr.o src/shared_ptr.cpp
src/shared_ptr.cpp: In member function ‘void shared_ptr::Storage::decr()’:
src/shared_ptr.cpp:24:39: error: no matching function for call to ‘shared_ptr::Storage::~Storage()’
   24 |         shared_ptr::Storage::~Storage();
      |                                       ^
src/shared_ptr.cpp:11:1: note: candidate: ‘shared_ptr::Storage::~Storage()’
   11 | shared_ptr::Storage::~Storage() {
      | ^~~~~~~~~~
src/shared_ptr.cpp:11:1: note:   candidate expects 1 argument, 0 provided
At global scope:
cc1plus: error: unrecognized command line option ‘-Wno-self-assign’ [-Werror]
cc1plus: all warnings being treated as errors
Makefile:17: recipe for target 'bin/shared_ptr.o' failed
make: *** [bin/shared_ptr.o] Error 1

про второе ожидаемо, разные компиляторы
первое не очень понимаю, почему происходит, если дописать this->, то компилируется (баг gcc?)
но вообще говоря единственный случай, когда нужно вручную звать деструктор, это https://isocpp.org/wiki/faq/dtors#placement-new

Возможно, Вы не очень поняли механизм освобождения памяти, поэтому напишу (относительно С):

  • все еще есть malloc + free, на каждый malloc должен быть free
  • создание объекта с помощью new это malloc + вызов конструктора
  • конструкторы и деструкторы это функции
  • деструктор нужен, чтобы очистить вложенные сущности
  • delete - обратная к new операция, зовет деструктор, а потом free
  • вызов new без парного вызова delete приводит к тому, что не зовется free и в программе утечка памяти

Сейчас утекают storage_ : зовется new, но не зовется delete

valgrind это видит

==2701==
==2701== HEAP SUMMARY:
==2701==     in use at exit: 16 bytes in 1 blocks
==2701==   total heap usage: 21 allocs, 20 frees, 77,593 bytes allocated
==2701==
==2701== 16 bytes in 1 blocks are definitely lost in loss record 1 of 1
==2701==    at 0x4C3017F: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2701==    by 0x109971: shared_ptr::shared_ptr(Matrix*) (in /home/nicesap/HSE/svn/nosivskoy.vladislav/lab_09/lab_09)
==2701==    by 0x109D2F: test_simple() (in /home/nicesap/HSE/svn/nosivskoy.vladislav/lab_09/lab_09)
==2701==    by 0x10949A: main (in /home/nicesap/HSE/svn/nosivskoy.vladislav/lab_09/lab_09)
==2701==
==2701== LEAK SUMMARY:
==2701==    definitely lost: 16 bytes in 1 blocks
==2701==    indirectly lost: 0 bytes in 0 blocks
==2701==      possibly lost: 0 bytes in 0 blocks
==2701==    still reachable: 0 bytes in 0 blocks
==2701==         suppressed: 0 bytes in 0 blocks
==2701==
==2701== For counts of detected and suppressed errors, rerun with: -v
==2701== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

чинится с помощью delete this. Про delete this: https://isocpp.org/wiki/faq/freestore-mgmt#delete-this
В целом delete this писать опасно и лучше не использовать, это задание - редкий случай, когда это уместно

Контрактов больше:

  • различные ограничения на ref_count_ во время работы со Storage
  • Storage ожидает not null Matrix* в конструкторе и этот указатель не станет нулевым никогда во время жизни объекта, включая деструктор
  • not null в operator -> (как работает x-> ?)

...

Note: See TracTickets for help on using tickets.