shared_ptr circular reference problem
Snape3058 opened this issue · comments
The function InvokeTimer::Create
will actually trigger a shared_ptr
circular reference that makes an object of InvokeTimer to hold its own shared_ptr
. If InvokeTimer::OnTimeTriggered
or InvokeTimer::OnCancled
is not finally invoked, it will probably lead to a memory leak.
According to issue #110 it seems that it could probably trigger some real memory leaks under some circumstances.
If you do this on purpose, could you please explain your ideas? And if you think it could be a problem, just simply reply to this issue to confirm our report.
Thank you.
This is the bug report generated by my static analyzer:
evpp/invoke_timer.cc:26:5: warning: Circular reference will lead to memory leak
it->self_ = it;
^~~~~~~~~~~~~~
Events:
evpp/invoke_timer.cc:25:56: note: Calling 'move<std::function<void ()> &>'
InvokeTimerPtr it(new InvokeTimer(evloop, timeout, std::move(f), periodic));
^~~~~~~~~~~~
evpp/invoke_timer.cc:25:56: note: Returning from 'move<std::function<void ()> &>'
InvokeTimerPtr it(new InvokeTimer(evloop, timeout, std::move(f), periodic));
^~~~~~~~~~~~
evpp/invoke_timer.cc:25:27: note: Calling constructor for 'InvokeTimer'
InvokeTimerPtr it(new InvokeTimer(evloop, timeout, std::move(f), periodic));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
evpp/invoke_timer.cc:14:50: note: Calling 'move<std::function<void ()> &>'
: loop_(evloop), timeout_(timeout), functor_(std::move(f)), periodic_(periodic) {
^~~~~~~~~~~~
evpp/invoke_timer.cc:14:50: note: Returning from 'move<std::function<void ()> &>'
: loop_(evloop), timeout_(timeout), functor_(std::move(f)), periodic_(periodic) {
^~~~~~~~~~~~
evpp/invoke_timer.cc:14:41: note: Calling move constructor for 'function<void ()>'
: loop_(evloop), timeout_(timeout), functor_(std::move(f)), periodic_(periodic) {
^~~~~~~~~~~~~~~~~~~~~~
evpp/invoke_timer.cc:14:41: note: Returning from move constructor for 'function<void ()>'
: loop_(evloop), timeout_(timeout), functor_(std::move(f)), periodic_(periodic) {
^~~~~~~~~~~~~~~~~~~~~~
evpp/invoke_timer.cc:25:27: note: Returning from constructor for 'InvokeTimer'
InvokeTimerPtr it(new InvokeTimer(evloop, timeout, std::move(f), periodic));
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
evpp/invoke_timer.cc:25:23: note: Allocate memory object: [Newed] HeapSymRegion{conj_$1{class evpp::InvokeTimer *, LC1, S1906113, #1}}
InvokeTimerPtr it(new InvokeTimer(evloop, timeout, std::move(f), periodic));
^
evpp/invoke_timer.cc:26:5: note: Pointer assignment: class std::shared_ptr<class evpp::InvokeTimer> HeapSymRegion{conj_$1{class evpp::InvokeTimer *, LC1, S1906113, #1}}->self_ = HeapSymRegion{conj_$1{class evpp::InvokeTimer *, LC1, S1906113, #1}} (pointer in the reference loop)
it->self_ = it;
^
evpp/invoke_timer.cc:26:5: note: Circular reference will lead to memory leak
it->self_ = it;
^~~~~~~~~~~~~~