9

I'm writing a library that will operate on multiple systems (some of which do not have malloc or a stdlib). In my stdlib (different lib), I am overriding the new and delete operators to make generic calls to functions (this example doesn't have these functions). Each system will override these generic calls to their respective memory allocation devices.

The issue is when I attempt to do this. Here is some stripped down example code to reproduce the issue:

#include <cstdlib>

void* operator new(unsigned long size) {
        return std::malloc(size); // would normally call an intermediate function which would be overridden by the system
}

void operator delete(void* object) {
        std::free(object); // would normally call an intermediate function which would be overridden by the system
}
void operator delete(void* object, unsigned long size) {
        std::free(object); // would normally call an intermediate function which would be overridden by the system
}

class MyClass {

};

int main() {
    MyClass* myClass = new MyClass();
    delete myClass;
}

When I build it with plain gcc-6 (no args) and run with valgrind (no args), I get this error:

==11219== Mismatched free() / delete / delete []
==11219==    at 0x4C2DD6B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11219==    by 0x108730: operator delete(void*, unsigned long) (in /home/chris13524/tmp/test.o)
==11219==    by 0x10875A: main (in /home/chris13524/tmp/test.o)
==11219==  Address 0x5200040 is 0 bytes inside a block of size 1 alloc'd
==11219==    at 0x4C2D1AF: operator new(unsigned long) (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==11219==    by 0x108745: main (in /home/chris13524/tmp/test.o)

It appears the delete operator is working correctly, but Valgrind is overriding my overridden new operator. Any idea how to fix this?

Removing the intermediate functions is not an option as I have other code in there.

Example of how it works on my real program (again, not shown in my example):

new => create => <intermediate code> => createImpl => malloc
create => <intermediate code> => createImpl => malloc

I'm using gcc v6.2.0, valgrind v3.12.0, and Ubuntu 16.10.

Chris Smith
  • 2,928
  • 4
  • 27
  • 59
  • I'm not such a big C++ guy, but your question caught my eye. I observe that the signature of your operator function does not match the standard signature you seem to be trying to override: `void* operator new ( std::size_t count )`. The argument type differs, or at least might do, depending on what `std::size_t` resolves to. – John Bollinger Nov 09 '16 at 15:08
  • @JohnBollinger Changing the type does not fix the issue. Either way, this would not be an option as some systems do not have `std::size_t`. – Chris Smith Nov 09 '16 at 15:10
  • Double check that your overloaded operators are actually being called (write something to output eg.). It looks like it called the built-in `operator new`, but your replacement `operator delete`, which is clearly a mismatch. Try this both with and without valgrind (to determine if valgrind is the culprit). Also, mentioning your compiler and version, as well as the valgrind version (and your platform) might help. – Sander De Dycker Nov 09 '16 at 15:16
  • Your example fails to reproduce the error for me on gcc 4.8.2 with valgrind 3.9. – ComicSansMS Nov 09 '16 at 15:20
  • @SanderDeDycker It's only calling `delete(void* object, unsigned long size)` – Chris Smith Nov 09 '16 at 15:20
  • 1
    @ComicSansMS Same, was unable to reproduce on v5 either. I'm using gcc v6 to get this. – Chris Smith Nov 09 '16 at 15:21
  • @SanderDeDycker Without Valgrind, it calls both `new` and `delete(2xargs)`. – Chris Smith Nov 09 '16 at 15:23
  • Here's a similar issue, but with Clang instead: https://stackoverflow.com/questions/25922895/clang-link-time-optimization-with-replaced-operator-new-causes-mismatched-free – Chris Smith Nov 09 '16 at 16:59
  • It seems that if I explicitly call the first delete: `operator delete (myClass)`, Valgrind will now override both of my functions (producing no output). – Chris Smith Nov 11 '16 at 13:03
  • See this bug I just created: https://bugs.kde.org/show_bug.cgi?id=372347 – Chris Smith Nov 11 '16 at 14:21
  • Any updates? having the same problem here.. – rcmgleite Jun 27 '17 at 04:16
  • 1
    @rcmgleite It hasn't been patched yet afaik, comment on the bug report. – Chris Smith Jun 27 '17 at 12:10

1 Answers1

2

Thanks to Paul Floyd, this bug has been fixed in commit 6ef6f738a. See bug report here.

However, this fix hasn't been released yet (as of June 2018), and will likely take longer to show up in distributions. If you need this fix now, I suggest building from source.

Chris Smith
  • 2,928
  • 4
  • 27
  • 59