Globally overloaded new inside template

For microcontrollers with small memory it's usually a good idea to globally overload the new and delete operators since they use a lot of memory, 80k in my case.

Inside Eclipse using ARM sourcery GCC and GNU ARM toolchain, I implemented the overloading inside the cruntime_opt.cpp file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//
// Define the 'new' operator for C++ to use the freeRTOS memory management
// functions. THIS IS NOT OPTIONAL!
//
void *operator new(size_t size){
	void *p=pvPortMalloc(size);
#ifdef	__EXCEPTIONS
	if (p==0) // did pvPortMalloc succeed?
		throw std::bad_alloc(); // ANSI/ISO compliant behavior
#endif
	return p;
}

//
// Define the 'delete' operator for C++ to use the freeRTOS memory management
// functions. THIS IS NOT OPTIONAL!
//
void operator delete(void *p){
	vPortFree( p );
}


It works like a charm no matter if the fno-exceptions is on or off. This flag is recognized by the __EXCEPTIONS keyword inside the overloaded implementation of the new operator.

I started to have problems once I created a template to deal with vectors.
Unfortunatelly the new operator inside the template is not the overloaded one, wich adds those extra unwanted 80kbytes to the code size.

The template I wrote:
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
#ifndef _VECTORTEMPLATE_HPP_
#define _VECTORTEMPLATE_HPP_

//Author: Daniel Kaminski de Souza

template<typename T>
class aVector
{
private:
	T* itsArray;
public:
	unsigned char size;
	template<typename... Values>
	aVector(const Values&... values)
	{
		T tsArray[] = {values...};
		size = sizeof...(values);
		itsArray = new T[size];
		for (unsigned char i=0; i< size; i++)
		{
			itsArray[i] = tsArray[i];
		}
	}
	~aVector()
	{
		delete itsArray;
	}
	T at(unsigned int i)
	{
		return itsArray[i];
	}
	void insert(unsigned char index, T item){
		T* newArray = new T[size+1];
		unsigned char i = 0;
		do{
			if(index == i){
				newArray[i] = item;
				break;
			}
			newArray[i] = itsArray[i];
			i++;
		}while(i < size);
		for (; i< size; i++)
			newArray[i+1] = itsArray[i];
		delete itsArray;
		itsArray = newArray;
		size = size+1;
	}
	T take(unsigned char index){
		T* newArray = new T[size-1];
		unsigned char i = 0;
		T returnItem;
		do{
			if(index == i){
				returnItem = itsArray[i];
				break;
			}
			newArray[i] = itsArray[i];
			i++;
		}while(i < size);
		size = size-1;
		for (; i< size; i++)
			newArray[i] = itsArray[i+1];
		delete itsArray;
		itsArray = newArray;
		return returnItem;
	}
};

#endif //_VECTORTEMPLATE_HPP_


The usage of this template is:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/* Declaration and Initialization of a vector */
aVector<anyTypeOne>nameOfVectorOne; // A vector without any itens inside;
aVector<anyTypeTwo>nameOfVectorTwo(anyTypeTwoValue1); // A vector with only one item 
aVector<anyTypeThree>nameOfVectorThree(anyTypeThreeValue1, anyTypeThreeValue2, ..., anyTypeThreeValueN); // A vector with N itens.

/* vector methods */
nameOfVectorOne.insert(0, anyTypeOneValue1); // insert at position 0 the item anyTypeOneValue1 
nameOfVectorOne.insert(0, anyTypeOneValue2); // insert at position 0 the item anyTypeOneValue2
nameOfVectorOne.insert(1, anyTypeOneValue2); // insert at position 1 the item anyTypeOneValue3

aVector<int>anIntVector(1, 2, 4, 5, 6);
anIntVector.size;
anIntVector.insert(2, 10);

anIntVector.take(3);
anIntVector.at(2);


What I want to do is to call the overloaded new and delete instead, inside the template.
Last edited on
Works (calls the user-provided operator new) for me, on gcc 4.6.1, linux.

Technically, your vector calls void* operator new[](size_t), but that function is required to call void* operator new(size_t), which you replaced.. Perhaps your compiler's operator new[] doesn't and it needs you to replace that one as well?
Last edited on
Thank you Cubbi. After I added also this new operator implementation to the cruntime_opt.cpp:

1
2
3
4
5
6
7
8
void *operator new[](size_t size){
	void *p=pvPortMalloc(size);
#ifdef	__EXCEPTIONS
	if (p==0) // did pvPortMalloc succeed?
		throw std::bad_alloc(); // ANSI/ISO compliant behavior
#endif
	return p;
} 


The called new became the user-provided operator new.
Thanks mate for that!

Maybe the different behavior we had was due to the language standard I used (-std=gnu++0x).

Regarding the same code, to me its giving a warning inside the templated class constructor. It says:

array subscript is above array bounds [-Warray-bounds] 

Any idea why?
Anyway I'm marking the topic's main issue solved.

inside the for loop:

1
2
3
4
		for (unsigned char i=0; i< size; i++)
		{
			itsArray[i] = tsArray[i];
		} 

Last edited on
Topic archived. No new replies allowed.