custom new/delete

dontpostalot
Posts: 5
Joined: Wed Sep 15, 2021 12:51 pm

custom new/delete

Postby dontpostalot » Wed Sep 15, 2021 1:11 pm

Hi,

I' trying to override the new/delete operators to add some data to any dynamically allocated memory, like this:

Code: Select all

void * operator new(size_t size)
{
	size_t* ret = (size_t*)malloc(size + sizeof(size_t*));
	*ret = 0;
	ret++;

	return (void*)ret;
}

void operator delete(void * ptr)
{
	size_t* ptrmem = (size_t*)ptr;
	ptrmem--;
	
	free((void*)ptrmem);
}
But the ESP32 errors (CORRUPT HEAP) and reboots. This does work on other compilers/architectures like MSC. What could be done to make this trick work?

ESP_Sprite
Posts: 9711
Joined: Thu Nov 26, 2015 4:08 am

Re: custom new/delete

Postby ESP_Sprite » Thu Sep 16, 2021 1:17 am

Not sure if that's it, but

Code: Select all

	size_t* ret = (size_t*)malloc(size + sizeof(size_t*));
I assume you want to add an extra size_t at the beginning of the allocated struct? In that case, your sizeof is wrong, it should be

Code: Select all

	size_t* ret = (size_t*)malloc(size + sizeof(size_t));
(Also, entirely offtopic, I'm surprised how quickly the word 'size' leads to semantic saturation.)

dontpostalot
Posts: 5
Joined: Wed Sep 15, 2021 12:51 pm

Re: custom new/delete

Postby dontpostalot » Thu Sep 16, 2021 7:37 am

No, sizeof(size_t) equals sizeof(size_t*), 4 on the ESP32. I was thinking what if there's a 'new' running before my sketch and the memory is released with my custom delete, that would cause a corrupted heap. So I used the extra memory as a tag, turns out there are 5 objects getting deleted that weren't created by the custom 'new'. The following sketch DOES run and prints out 5 continuously:

Code: Select all

int cntbad = 0;

void * operator new(size_t size)
{
  size_t* ret = (size_t*)malloc(size + sizeof(size_t*));
  *ret = 37; // tag it!
  ret++;

  return (void*)ret;
}

void operator delete(void * ptr) noexcept
{
  size_t* ptrmem = (size_t*)ptr;
  ptrmem--;
  if (*ptrmem != 37) { // not generated by our new
    ptrmem++;  
    cntbad++; 
  }

  free((void*)ptrmem);
}

void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200, SERIAL_8N1);
}

void loop() {
  // put your main code here, to run repeatedly:
Serial.println("loep");
Serial.println(cntbad);
delay(1000);
}


Of course I can't tag all these pieces of memory, that wouldn't be very efficient, but maybe it's just the first 5 objects that are being deleted. So I changed the line that said 'if (*ptrmem != 37)' to 'if (cntbad < 5)', and it all still worked fine.

This is an acceptable workaround imo, but it still feels wrong. Whatever code is initing my sketch shouldn't call new or delete at all. If anyone has a better solution please let me know.

Who is online

Users browsing this forum: No registered users and 29 guests