How to write destructor ( unique_ptr<T>).

I am working on a custom container class. My main method runs correctly. Iterating the contents and printing via cout. Once complete it then throws a runtime error.

HEAP CORRUPTION DETECTED: before Normal block (#3) at 0x00A60F40 CRT detected that the application wrote to memory before the start of the heap buffer.

My IDE its putting a breakpoint on my destructor which is currently empty. I am guessing the cause of this error could be here.

However, I am not sure how to correctly write my destructor. From my understanding, I need to destroy the T[] which has created via NEW in the constructor. Access to this array is via std::unique_ptr<T[]> m_buffer. I have tried serval methods of destroying the array to solve the error but none have worked.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

std::unique_ptr<T[]> m_buffer;

CONSTRUCTOR.

RingBuffer(std::size_t capacity)
		: m_buffer(new T[capacity + 1]),
		m_base(m_buffer.get()),
		m_limit(m_base + capacity + 1), m_begin(m_base), m_end(m_base)
	{}

DESTRUCTOR ( not complete )

~RingBuffer()
	{
		

	}	
	
Last edited on
Edit: this first part is totally wrong:

A std::unique_ptr<T> works as a T*, i.e.
std::unique_ptr<T> m_buffer;
is very similar to
T* m_ buffer;

If you declare a std::unique_ptr<T[]>, you declare something like a T** or a T*[] or a T[][], i.e.:

std::unique_ptr<T[]> m_buffer;

is very similar to

T* m_ buffer[];

Is that what you want? A 2D array?
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

To initialize a std::unique_ptr you can use std::make_unique instead of a ‘plain’ new.

A std::unique_ptr cleans the owned memory when it gets out of scope, so there could be nothing to implement in your destructor.
Last edited on
I am presuming I must have missed something in my destructor, due to the error

I stepped through the entire program and the error is thrown once the destructor is reached.

>A std::unique_ptr cleans the owned memory when it gets out of scope, so there could be nothing to implement in your destructor.

Maybe the error is being caused elsewhere then

Edit: just skip this post: it’s totally wrong

May I insist?
Do you really want a 2D array?

Because here you ask for a 2D array:
 
std::unique_ptr<T[]> m_buffer;


and here you try to initialize it as if it were a mono-dimensional array:
 
m_buffer(new T[capacity + 1])

That definitely may cause your code to crash (that’s unpredictable).

Last edited on
I am not really understanding how std::unique_ptr<T[]> m_buffer , is a pointer to a 2d array.

I am able to compile and interact with my container class. The error occurs at the end of the program

Are more complete skeleton of my class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57

Template <typename T>
class RingBuffer {
	
	template <typename, typename, typename>
	friend class _RBIterator;
public:
	using size_type = std::size_t;
	using value_type = T;
	using iterator = _RBIterator<T, T*, T&>;
	using const_iterator = _RBIterator<T, const T*, const T&>;

	RingBuffer(std::size_t capacity)
		: m_buffer(new T[capacity + 1]),
		m_base(m_buffer.get()),
		m_limit(m_base + capacity + 1), m_begin(m_base), m_end(m_base)
	{}

	RingBuffer(const RingBuffer& pattern)
		: RingBuffer(pattern.capacity())
	{

	}

	~RingBuffer()
	{
		
	}

	
	RingBuffer& operator=(const RingBuffer& rhs) = delete;

	iterator begin()
	const_iterator begin() const
	const_iterator cbegin() const
	size_type capacity() const
	void clear()
	bool empty() const
	iterator end()
	const_iterator end() const
	const_iterator cend() const
	T& front()
	const T& front() const
	void pop_front()
	void push_back(const T& elem)
	size_type size() const
	
private:
	
	std::unique_ptr<T[]> m_buffer;

	T* m_base;  
	T* m_limit;  
	T* m_begin;  

	T* m_end; 
Last edited on
@goozeberry, yes, you’re right, I was totally missing the point and focusing on a wrong syntax.
I’m amending my previous posts.
It seems the object is constructed and deleted correctly.
You might start from your skeleton and add functionalities to both your class and the driver program until you come across the error.
Just compile often.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <cstdio>   // we need a definition of std::size_t
#include <memory>


template <typename T> class RingBuffer {
public:
    explicit RingBuffer(std::size_t capacity);

private:
    std::unique_ptr<T[]> m_buffer;
    T* m_base;
    T* m_limit;
    T* m_begin;
    T* m_end;
};


template <typename T> RingBuffer<T>::RingBuffer(std::size_t capacity)
    : m_buffer { std::make_unique<T[]>(capacity + 1) }
    , m_base { m_buffer.get() }
    , m_limit { m_base + capacity + 1 }
    , m_begin { m_base }
    , m_end { m_base }
{}


void testDestruction();


int main()
{
    testDestruction();
}


void testDestruction()
{
    [[maybe_unused]] RingBuffer<char> rb(1000);
}

UPDATE :

The original error -

HEAP CORRUPTION DETECTED: before Normal block (#3) at 0x00A60F40 CRT detected that the application wrote to memory before the start of the heap buffer.

was being caused by how I was handling my pointers in the push_back method in my ring buffer and not connected to the destructor





Last edited on
Topic archived. No new replies allowed.