I am currently working on a threadsafe circular buffer for storing pointers. As basis I used the code from this thread: Thread safe implementation of circular buffer. My code is shown below.
Because I want to store pointers in the circular buffer, I need to make sure that allocated memory is deleted, in case the buffer is full and the first element is overwritten, as mentioned in the boost documentation:
When a circular_buffer becomes full, further insertion will overwrite the stored pointers - resulting in a memory leak. 1
So I tried to delete the first element in the add method, in case the buffer is full and the type T of the template is actually a pointer. This leads to a C2541-error, because I try to delete an object, which is not seen as a pointer.
Is my basic approach correct? How can I solve the above issue?
#pragma once #include <boost/thread/condition.hpp> #include <boost/thread/mutex.hpp> #include <boost/thread/thread.hpp> #include <boost/circular_buffer.hpp> #include <type_traits> #include "Settings.hpp" template <typename T> class thread_safe_circular_buffer : private boost::noncopyable { public: typedef boost::mutex::scoped_lock lock; thread_safe_circular_buffer(bool *stop) : stop(stop) {} thread_safe_circular_buffer(int n, bool *stop) : stop(stop) {cb.set_capacity(n);} void add (T imdata) { monitor.lock(); std::cout << "Buffer - Add Enter, Size: " << cb.size() << "\n"; if(cb.full()) { std::cout << "Buffer - Add Full.\n"; T temp = cb.front(); if(std::is_pointer<T>::value) delete[] temp; } std::cout << "Buffer - Push.\n"; cb.push_back(imdata); monitor.unlock(); std::cout << "Buffer - Add Exit.\n"; } T get() { std::cout << "Buffer - Get Enter, Size: " << cb.size() << "\n"; monitor.lock(); while (cb.empty()) { std::cout << "Buffer - Get Empty, Size: " << cb.size() << "\n"; monitor.unlock(); std::this_thread::sleep_for(std::chrono::milliseconds(1000)); if(*stop) return NULL; monitor.lock(); } T imdata = cb.front(); // Remove first element of buffer std::cout << "Buffer - Pop.\n"; cb.pop_front(); monitor.unlock(); std::cout << "Buffer - Get Exit.\n"; return imdata; } void clear() { lock lk(monitor); cb.clear(); } int size() { lock lk(monitor); return cb.size(); } void set_capacity(int capacity) { lock lk(monitor); cb.set_capacity(capacity); } bool *stop; private: boost::condition buffer_not_empty; boost::mutex monitor; boost::circular_buffer<T> cb; };
tempas an array (delete[] temp;) when it'sT temp;T Tempis not clear.