Page 1 of 1

custom new/delete

Posted: Wed Sep 15, 2021 1:11 pm
by dontpostalot
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?

Re: custom new/delete

Posted: Thu Sep 16, 2021 1:17 am
by ESP_Sprite
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.)

Re: custom new/delete

Posted: Thu Sep 16, 2021 7:37 am
by dontpostalot
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.