I am writing a C++ application which used QT libraries. I want to detect memory leaks in my application and in QT. So, I have overloaded the new and delete operator in my main.cpp using this reference http://lists.trolltech.com/qt-interest/2002-04/msg00933.html, but QT is not using the overloaded operators. Apparently, it appears to be a namespace issue. How to resolve this.
int numAllocUnits = 0;
ofstream myLogFile("/root/memLeak.log");
class MemoryLeak_Manav
{
public:
MemoryLeak_Manav() {
if (!myLogFile.is_open()) {
cout << "Unable to open file";
}
myLogFile << "Memory Leak Detection log File" << endl;
printf("Memory Leak Detection On ... ");
}
public:
~MemoryLeak_Manav() {
myLogFile.close();
if(numAllocUnits)
printf("\nError: Memory leak detected: %d\n\n", numAllocUnits);
else printf("\nNo memory leak detected.\n\n");
}
public:
void *operator new [] (size_t size);
void *operator new (size_t size);
void operator delete [] (void *p);
void operator delete (void *p);
};
void * MemoryLeak_Manav::operator new(size_t size)
{
void *newPtr;
numAllocUnits++;
newPtr = malloc(size);
printf("malloc [%p allocated %d bytes]\n", newPtr, size);
myLogFile << "malloc [" << newPtr << "allocated" << size << "bytes" << endl;
return newPtr;
}
void MemoryLeak_Manav::operator delete(void *p)
{
numAllocUnits--;
free(p);
}
void * MemoryLeak_Manav::operator new [] (size_t size)
{
void *newPtr;
numAllocUnits++;
newPtr = malloc(size);
printf("malloc [%p allocated %d bytes]\n", newPtr, size);
myLogFile << "malloc [" << newPtr << "allocated" << size << "bytes" << endl;
return newPtr;
}
void MemoryLeak_Manav::operator delete [] (void *p)
{
numAllocUnits--;
printf("free %p\n", p);
myLogFile << "free" << p << endl;
free(p);
}
The memLeak.log file is empty and I am not seeing any printf's messages also.
You can't overload new in a library because a library is already compiled. To replace new in Qt, you have to obtain Qt sources, put overload in whatever base file of them and then recompile. It isn't as hard as it sounds, by the way.
You made your operators member of a class. Like that, they will only be used within the namespace of the class.
Just define the operators as global operators (without a class) and it should work
If you can test it on Linux, then have a look at using the Valgrind Memcheck tool.
This provides very detailed information on leaks and bad memory use (double free, corruption, partial free), including full stack traces.
Related
so this is my code [ notice that I commented the cstr and destructor]
#include <iostream>
#include <stdlib.h>
#include <array>
class MyIntClass
{
int _mymember;
public:
// MyIntClass(){}
// ~MyIntClass(){}
void *operator new(size_t size)
{
std::cout << "new: Allocating " << size << " bytes of memory" << std::endl;
void *p = malloc(size);
return p;
}
void operator delete(void *p)
{
std::cout << "delete: Memory is freed again " << std::endl;
free(p);
}
void *operator new[](size_t size)
{
std::cout << "new: Allocating " << size << " bytes of memory" << std::endl;
void *p = malloc(size);
return p;
}
void operator delete[](void *p)
{
std::cout << "delete: Memory is freed again " << std::endl;
free(p);
}
};
void line(){
std::cout << "\n--------------------------------------------------\n" << std::endl;
}
int main()
{
line();
std::cout << "Using new overloading and malloc\nWe will create one object of MyIntClass that is supposed to be 4 bytes" << std::endl;
MyIntClass *m1 = new MyIntClass();
line();
//I want to create an array of the MyIntClass of two objects
std::cout << "Now we create array of MyIntClass using <array> header" << std::endl;
std::array<MyIntClass, 2> z = {};
std::cout << " The elements in the array z = "<< z.size() <<std::endl;
std::cout << "The memory allocated for array z = " << sizeof(z) << std::endl;
line();
std::cout << "\nNow we create array using new[] overloading and malloc " << std::endl;
MyIntClass *i = new MyIntClass[2]();
delete[] i;
}
now the result is as follow:
Using new overloading and malloc
We will create one object of MyIntClass that is supposed to be 4 bytes
new: Allocating 4 bytes of
memory
Now we create array of MyIntClass using <array> header
The elements in the array z = 2
The memory allocated for array z = 8
Now we create array using new[] overloading and malloc
new: Allocating 8 bytes of memory
To me as inexperienced C++ programmer I think every thing is working as expected
Now If I uncomment the constructor the same result will happen
however when I uncomment the destructor different result will occur
Now we create array using new[] overloading and malloc
new: Allocating 12 bytes of memory
So my question is what is the explanation for this:
creating array of two objects each is 4 bytes will result in 8byte memory allocation for the array in both methods using the array library or the overloading the new[] and malloc.
however when we have a destructor for the object the malloc will allocate 12 bytes not 8 bytes for this array of 2 elements.
I saw this question on SO but it didn't explain my case
following is my compiler version :
gcc version 8.2.0 (MinGW.org GCC-8.2.0-3)
The reason for extra allocated memory is that the compiler needs to know the number of elements in the array in order to be able to call destructors on each element of the array when you call delete[]. For trivially destructible types the compiler doesn't need to call destructor, so the extra space for the array size is not needed.
I have some C++ unit tests using google test. Threw together some code to override the new/delete operators to check for leaks in the unit tests. Having an issue though. Some of the google test new/deletes use my overridden methods, but some don't, so I get false errors in the tracking code -- sometimes seeing that memory was leaked even though it was really deleted and sometimes seeing that malloc returns
Here is my minimal new/delete overrides (just prints the addresses for manual inspection):
void * operator new(size_t size)
{
void * addr = malloc(size);
std::cout << " tracking create: " << addr << "(size " << size << ")" << std::endl;
return addr;
}
void * operator new[](size_t size)
{
void * addr = malloc(size);
std::cout << " tracking create: " << addr << "(size " << size << ")" << std::endl;
return addr;
}
void operator delete(void * addr) noexcept
{
std::cout << " tracking delete: " << addr << std::endl;
free(addr);
}
void operator delete[](void * addr) noexcept
{
std::cout << " tracking delete: " << addr << std::endl;
free(addr);
}
And here is the google test line that does NOT go through my overridden delete (gtest-port.h):
void reset(T* p = NULL) {
if (p != ptr_) {
if (IsTrue(sizeof(T) > 0)) { // Makes sure T is a complete type.
delete ptr_;
}
ptr_ = p;
}
}
When I break on the delete ptr_ line in gdb, then step, it steps directly to the ptr_ = p line, so there isn't something else overriding that delete.
I'm building gtest as an archive file and linking it in when I build my unit tests. In case it matters: I'm on windows building with mingw using cygwin.
Here's a minimal example, 2 files min.cpp and minmain.cpp. Here's min.cpp:
#include <iostream>
#include <string>
// Overload the new/delete operators to check for memory errors
void * operator new(size_t size)
{
void * addr = malloc(size);
std::cout << " tracking create: " << addr << "(size " << size << ")" << std::endl;
return addr;
}
void * operator new[](size_t size)
{
void * addr = malloc(size);
std::cout << " tracking create: " << addr << "(size " << size << ")" << std::endl;
return addr;
}
void operator delete(void * addr) noexcept
{
std::cout << " tracking delete: " << addr << std::endl;
free(addr);
}
void operator delete[](void * addr) noexcept
{
std::cout << " tracking delete: " << addr << std::endl;
free(addr);
}
minmain.cpp:
#include "gtest/gtest.h"
TEST(MinTest, MinimalTest)
{
int test = 5;
test++;
test++;
test++;
ASSERT_EQ(test, 8);
}
int main(int argc, char *argv[])
{
char* t = new char();
t[0] = 't'; std::cout << "t is " << t[0] << std::endl;
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
compiled with:
/bin/x86_64-w64-mingw32-g++.exe -std=c++11 -D_USE_MATH_DEFINES -g -Wall -I../third_party/googletest-1.8.0/googletest/include -c min.cpp -o min.o
to create the min.o, then compile main and link all together with:
/bin/x86_64-w64-mingw32-g++.exe -std=c++11 -D_USE_MATH_DEFINES -g -Wall -I../third_party/googletest-1.8.0/googletest/include -o minmain minmain.cpp min.o ../third_party/googletest-1.8.0/googletest/make/gtest_main.a
Using version 1.8.0 of gtest, break at gtest-port.h:1145 to get to the delete ptr_ line, then step.
Here is some sample output from running the example above (first few lines of output):
tracking create: 0x30e4c0(size 392)
tracking create: 0xa477e0(size 392)
tracking create: 0xa477e0(size 392)
tracking create: 0xa477e0(size 392)
tracking create: 0xa477e0(size 392)
tracking create: 0xa47b80(size 28)
tracking delete: 0xa47b80
The fact that I get tracked creates on the same address with no tracked deletes in between is a problem, because there were deletes in between allowing the same address to be allocated again, but those deletes did not go through my overridden delete operator.
Why does that delete ptr_; line in gtest not use my overridden delete function?
Looks like this is a bug in MinGW:
MinGW bug #634
A work-around is to link the static version of libstdc++ instead of letting it link the dynamic library. Not the most ideal solution, but it's good enough for my unit tests and it allows me to override correctly.
I modified by compile/link command to the following to do this:
/bin/x86_64-w64-mingw32-g++.exe -std=c++11 -D_USE_MATH_DEFINES -g -Wall -I../third_party/googletest-1.8.0/googletest/include -o minmain minmain.cpp min.o ../third_party/googletest-1.8.0/googletest/make/gtest_main.a /cygdrive/c/cygwin64/lib/gcc/x86_64-w64-mingw32/6.4.0/libstdc++.a
Mucho thanko to Peter for putting me down the right path to finding this.
I have here some line of code. What I am trying to do here is that I would like to allocate 10 objects using overloaded operator new and on the 11th "run out of memory" and throw an exception. I added a static member function that reclaims the memory allocated for the 10th object so that I can use the address back and allocate it to a new object.
I'm still on the learning process for c++ so your critics are highly appreciated.
Help me evaluate my program. I don't know how I can reclaim the memory and then use the address to allocate the next new object.
Thank you.
P.S. how can I use 'this' in overload operator new?
#include <iostream>
#include <cstdlib>
using namespace std;
int count=0;
class RunOutOfMemory : public exception{
public:
const char * Message(){
return "Run out of memory!";
}
};
class ObjectAllocation{
public:
ObjectAllocation(){
cout << count << "Object Allocated at " << &this[count] << endl;
}
//Operator new overloaded
void * operator new(){
count++;
if(count>=11){
throw RunOutOfMemory();
}
}
//Reclaim memory allocated for 10th instance
//so that a new object can be instantiate on its memory address
static void reclaim(){
//delete?
}
};
int main(int argc, char * argv[]){
ObjectAllocation * objAlloc;
int counter=0;
cout << &objAlloc << endl;
while(counter<=20){
counter++;
try{
objAlloc = new ObjectAllocation();
cout << &objAlloc[counter] << endl;
}catch(RunOutOfMemory room){
cout << room.Message() << endl;
objAlloc.reclaim();
}
}
}
I want to overload the operator new[] to get the number of how many objects are to be created.
the best possible solution is to overload new[] in a way that the when creating an object using new[] would not necessitate the caller to write any extra code.
i.e using simply:
Myclass objectsArray = new Myclass[5];
example overload:
class Myclass
{
...
public:
void* operator new[](size_t size)
{
int numberOfObjects = figure out how to get number of objects to be created by this call to new[]
std::cout << "requesting: " << numberOfObjects << " objects" << std::endl;
void * temp = malloc(size) ;
return temp ;
}
...
}
the following example program:
Myclass objectsArray = new Myclass[4];
would output:
requesting: 4 objects
edit:
I want to do this just in MyClass not globaly
edit:
I'm on ‎Lubuntu 12.0 with GCC version 4.8.1
edit: Purpose of the question:
I'm using a custom memory pool allocator that can't allocate arrays out of the box. so I need to know how many objects are requested and create them one by one using a loop with the pool allocator.
You need to define a class-specific operator new. This works for me, but beware of alignment, derived classes sizes, and allocation overhead issues in the count/sizeof(MyClass) expression:
#include <iostream>
#include <memory>
#include <new>
struct MyClass {
int dummy[8];
void *operator new[](std::size_t count) {
std::cout << "allocating " << count << " bytes, " << ((count-sizeof(void*))/sizeof(MyClass)) << " items\n";
return ::operator new[](count);
}
};
int main() {
auto x = std::make_unique<MyClass[]>(10);
}
(prints: allocating 10 items) I think one can determine the exact overhead for your compiler/stdlib combination empirically by doing something like:
#include <iostream>
#include <memory>
#include <new>
struct MyClass {
char c;
char d;
virtual ~MyClass() {} // needed for introducing overhead
void *operator new[](std::size_t count) {
void *p = ::operator new[](count);
std::cout << "allocating " << count << " bytes\n";
return p;
}
};
int main() {
for( auto count : { 1, 5, 10, 20 } ) {
std::cout << "allocating " << sizeof(MyClass) << " * " << count << " items\n";
auto x = new MyClass[count];
delete[] x;
}
}
This will print, in my machine (and on Coliru):
allocating 16 * 1 items
allocating 24 bytes, 1 items
allocating 16 * 5 items
allocating 88 bytes, 5 items
allocating 16 * 10 items
allocating 168 bytes, 10 items
allocating 16 * 20 items
allocating 328 bytes, 20 items
So, our count/sizeof(MyClass) (here) should be something like
(count-sizeof(void*))/sizeof(MyClass)
But YMMV, etc.
LAST EDIT (I hope)
I had success on 64-bits linux (clang-3.4, clang-3.5 & gcc-4.8, libstdc++ & libc++) with the following how_many_elements function:
template<class T>
std::size_t how_many_elements(std::size_t bytes) {
return (bytes -
((!std::is_trivially_destructible<T>::value)*sizeof(void*))
) / sizeof(T);
}
So your operator new becomes something like:
void *operator new[](std::size_t count) {
std::cout << "allocating " << count << " bytes, " << how_many_elements<MyClass>(count) << " items\n";
return ::operator new[](count);
}
But I have not tested it in 32-bits environments and the YMMV still applies. And remember to replicate the operator new for every derived class of MyClass, obviously replacing MyClass for MyDerivedClass or whatever...
I have an assignment that requires me to create a "Heap" class that allocates and deallocates memory. I believe that my code works and the solution builds and runs properly but I want to make sure that I am not getting any memory leaks. I also need to add some code that checks if the desired amount to be allocated to the heap is even available...if someone were to allocate a very large amount. How is it possible to check if the memory allocated on the heap is available or NULL if there is not enough memory. Here is my code so far:
#include <iostream>
using namespace std;
class Heap{
public:
double* allocateMemory(int memorySize)
{
return new double[memorySize];
};
void deallocateMemory(double* dMemorySize)
{
delete[] dMemorySize;
};
};
int main()
{
Heap heap;
cout << "Enter the number of double elements that you want to allocate: " << endl;
int hMemory;
const int doubleByteSize = 8;
cin >> hMemory;
double *chunkNew = heap.allocateMemory(hMemory);
cout << "The amount of space you took up on the heap is: " <<
hMemory*doubleByteSize << " bytes" <<
starting at address: " << "\n" << &hMemory << endl;
heap.deallocateMemory(chunkNew);
system("pause");
return 0;
}
It's not necessary to check beforehand, just try to allocate memory and if you can't, then catch the exception. In this case it is of type bad_alloc.
#include <iostream>
#include <new> // included for std::bad_alloc
/**
* Allocates memory of size memorySize and returns pointer to it, or NULL if not enough memory.
*/
double* allocateMemory(int memorySize)
{
double* tReturn = NULL;
try
{
tReturn = new double[memorySize];
}
catch (bad_alloc& badAlloc)
{
cerr << "bad_alloc caught, not enough memory: " << badAlloc.what() << endl;
}
return tReturn;
};
Important note
Be sure to guard against double-freeing memory. One way to do that would be to pass your pointer to deallocateMemory by reference, allowing the function to change the pointer value to NULL, thereby preventing the possibility of delete-ing the pointer twice.
void deallocateMemory(double* &dMemorySize)
{
delete[] dMemorySize;
dMemorySize = NULL; // Make sure memory doesn't point to anything.
};
This prevents problems like the following:
double *chunkNew = heap.allocateMemory(hMemory);
heap.deallocateMemory(chunkNew);
heap.deallocateMemory(chunkNew); // chunkNew has been freed twice!