Placement new

Quick question regarding placement new, i'm trying to make a very simple vector however i'm struggling to understand how I assign an item to a particular index in the array, please could you point me in the right direction?

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
#ifndef __VECTOR__
#define __VECTOR__

#include <cstddef>
#include <initializer_list>

template <typename T>
class jvector {
private:
	std::size_t elems{ 0 };
	int capacity{ 10 };
	T* allocator{ nullptr };
public:
	T* begin{ nullptr };
	T* end{ nullptr };
	jvector() {};
	jvector(const std::initializer_list<T> items)
	{
		allocator = new T[capacity];
		begin = allocator;
		for (T i : items)
		{
			push_back(i);
			elems++;
		}
		end = allocator[elems];
	}
	void push_back(const T& item)
	{
		allocator[end] = item; //this is a compiler error, i'm not 
                //sure how to construct "item" at this location
		end++;
		elems++;
	}
};

#endif 
end is a pointer. Here is how to set the value in something being pointed at:
*end = item;

Remember to watch out for when you have inserted so many items that your array is full. In those cases, you'll need to reallocate your array to make it bigger.

I've tried that but I still get an illegal indirection (expression doesn't evaluate to a pointer) compiler error:

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
#ifndef __VECTOR__
#define __VECTOR__

#include <cstddef>
#include <initializer_list>

template <typename T>
class jvector {
private:
	std::size_t elems{ 0 };
	int capacity{ 10 };
	T* allocator{ nullptr };
public:
	T* begin{ nullptr };
	T* end{ nullptr };
	jvector() {};
	jvector(const std::initializer_list<T> items)
	{
		allocator = new T[capacity];
		begin = allocator;
		for (T i : items)
		{
			push_back(i);
			elems++;
			end++;
		}
	}
	void push_back(const T& item)
	{
		*allocator[elems+1] = item; //illegal indirection, do I have to define the [] 
                 //operator myself?
		end++;
		elems++;
	}
};

#endif 
I've tried that

I don't see it in your code.

I see this:
*allocator[elems+1] = item
but this is a mess of misunderstanding. allocator is an array, therefore allocator[elems+1] is a (reference to) one element in that array, therefore *allocator[elems+1] is an attempt to pretend that allocator[elems+1] is a pointer and to dereference it, and the compiler doesn't like it when you pretend something that isn't a pointer is a pointer.


*end = item; would work.
allocator[elems+1] = item; would work.
ah yes, allocator[elems+1] = item works. Thanks for the explanation!
Correct me if I'm wrong, but I don't think placement new is being used here.
yeah I think i've misunderstood the concept. I've actually come across 2 other problems in the below code. #1 I get a heap corruption when reallocate() is invoked, and #2 if I run the code in main below, all 5 numbers print, but on line 2 it prints a weird int like -857842 and can't see what's wrong either in print() or push_back()

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
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#ifndef __VECTOR__
#define __VECTOR__

#include <cstddef>
#include <initializer_list>
#include <iostream>

template <typename T>
class jvector {
private:
	std::size_t elems{ 0 };
	int capacity{ 10 };
	T* allocator{ nullptr };
public:
	T* begin{ nullptr };
	T* end{ nullptr };
	jvector() 
	{
		allocator = new T[capacity];
		begin = allocator;
		end = allocator;
	}
	jvector(const std::initializer_list<T> items)
	{
		allocator = new T[capacity];
		begin = allocator;
		end = allocator;
		for (T i : items)
		{
			push_back(i);
		}
	}
	void reallocate()
	{
		capacity *= 2;
		T* reallocator = new T[capacity];
		T* iterator = begin;
		int i = 0;
		while (iterator != end + 1)
		{
			reallocator[i] = iterator[i];
			iterator++;
                        i++;
		}
		delete[] allocator;
		allocator = reallocator;
                begin = allocator;
		*end = allocator[elems];
	}
	void push_back(const T item)
	{
		if (empty())
		{
			allocator[elems] = item;
		}
		else
		{
			if (elems == capacity)
			{
				reallocate();
			}
			allocator[elems + 1] = item;
		}
		end++;
		elems++;
	}
	void pop_back()
	{
		if (empty())
			return;
		end--;
		elems--;
	}
	bool empty()
	{
		return (elems == 0 ? true : false);
	}
	void print()
	{
		T* iterator = begin;
		while (iterator != end+1)
		{
			std::cout << *iterator << std::endl;
			iterator++;
		}
	}
};

//MAIN

#include "vector.hpp"
#include <iostream>
int main(int argc, char** argv)
{
	jvector<int> vec = { 55, 66, 77, 88, 885 };
	vec.print();
	getchar();

	return 0;
}

#endif 
Last edited on
Remember that arrays are zero-indexed. So, if you have 1 element in the array, that element is stored in allocator[0]. and the next new element you put into the array will go into allocator[1] .

(BTW, allocator seems like a really weird name to call the array you're using to store the vector elements. An allocator is an object that performs allocation, not storage space.)
Last edited on
Topic archived. No new replies allowed.