I was just wondering how you could create a system memory leak using C++. I have done some googling on this but not much came up, I am aware that it is not really feasible to do it in C# as it is managed code but wondered if there was a simple way to do this with C++? I just thought it would be interesting to see how much the system suffers because of code not being written properly. Thanks.
A memory leak occurs when you call new without calling a corresponding delete later. As illustrated in this sample code:
int main() {
// OK
int * p = new int;
delete p;
// Memory leak
int * q = new int;
// no delete
}
Create pointer to object and allocate it on the heap
Don't delete it.
Repeat previous steps
????
PROFIT
int main() {
while(true) new int;
}
There are many kinds of memory leaks:
Allocated memory that is unreleasable because nothing points to it.
These kind of leaks are easy to create in C and C++. They are also pretty easy to prevent, easy to detect, and easy to cure. Because they are easy to detect there are lots of tools, free and commercial, to help find such leaks.
Still-accessible allocated memory that should have been released a long time ago.
These kinds of leaks are much harder to detect, prevent, or cure. Something still points to it, and it will be released eventually -- for example, right before exit(). Technically speaking, this isn't quite a leak, but for all practical purposes it is a leak. Lots of supposedly leak-free applications have such leaks. All you have to do is run a system profile to see some silly application consume ever more memory. These kinds of leaks are easy to create even in managed languages.
Allocated memory that should never have been allocated in the first place.
Example: A user can easily ask Matlab to creating these kinds of leaks. Matlab is also rather aggressive at creating these kinds of leaks. When Matlab gets a failure from malloc it goes into a loop where it waits for a bit and then retries the malloc. Meanwhile, the OS frantically tries to deal with the loss of memory by shuffling chunks of programs from real memory into virtual memory. Eventually everything is in virtual memory -- and everything creeps to a standstill.
Just write an application which allocates "a lot of data" and then blocks until it is killed. Just run this program and leave it running.
class ClassWithLeakedMemory{
private:
char* str;
public:
ClassWithLeakedMemory(){
str = new char[100];
}
~ClassWithLeakedMemory(){
cout<<"We are not freeing the dynamically allocated string memory"<<endl;
}
};
class ClassWithNoLeakedMemory{
private:
char* str;
public:
ClassWithNoLeakedMemory(){
str = new char[100];
}
~ClassWithNoLeakedMemory(){
cout<<"We are freeing the dynamically allocated string memory"<<endl;
delete[] str;
str = null;
}
};
int main() {
//we are creating an automatic object of the ClassWithleakedMemory
//when we will come out of the main, this object will be
//out of scope. hence it will be deleted. so destructor will
//be called. but in the destructor, we have not specifically
//deleted the dynamically allocated string.
//so the stack based pointer object str will be deleted but the memory
//it was pointing to won't be deleted. so we will be left with an
//unreferenced memory. that is memory leak.
ClassWithLeakedMemory objectWithLeakedmemory;
ClassWithNoLeakedMemory objectWithNoLeakedmemory;
return 0;
}
The way the stack based pointer object refers to the dynamically allocated memory in both the classes can be shown pictorially as below:
In C#, just use P/Invoke to allocate a lot of memory, resource handles and keep them around.
You can use unmanaged code just fine in a simple C# harness
When an object that is created using new is no longer referenced, the delete operator has to be applied to it. If not, the memory it occupies will be lost until the program terminates. This is known as a memory leak. Here is an illustration:
#include <vector>
using namespace std;
void memory_leak(int nbr)
{
vector<int> *ptrVector = new vector<int>(nbr);
// some other stuff ...
return;
}
If we return without calling delete on the object (i.e. delete ptrToVector) a memory leak occurs. To avoid this, don't allocate the local object on the memory heap but instead use a stack-allocated variable because these get automatically cleaned up when the functions exits. To allocate the vector on the run-time stack avoid using new (which creates it on the heap) and the pointer.
It's as simple as:⠀⠀⠀
new int;
#include <stdio.h>
void main(){
for(int i = 0; i < 1000; i++)
double* ptr = (double*)malloc(1000000*sizeof(double))
//free(ptr);
ptr = NULL;
}
note : the hashed line of code caused a memory leak while the process allocated it and did't return it back to the OS
Related
I am taking a class on c++ for which I need to write a simple program that leaks memory on purpose. I have tried this by creating new char [] and not deleting them, but this does not seem to work. Below is the complete code I have tried.
#include <iostream>
#include <cstring>
int main()
{
int i=1;
while (i<1000){
char *data = new char [100000000];
*data = 15;
i++;
}
}
When I watch the memory usage of the program it does not grow so it is not leaking any memory. I just get a bad allocation error.
I think the simplest case of memory leakage is dynamically creating an object then immediately losing the reference to it. In this short example, you are immediately losing a reference to the variable you've created, causing the memory leak. Memory leaks in small, contrived programs like these make it hard to appreciate memory leaks because as soon as a program exits, the operating system reclaims the memory the program allocated.
The problem becomes serious when the program runs for long periods of time. The memory leak is exacerbated and computer performance is noticeable hampered.
Example:
#include <iostream>
// Object is being created, allocated on the heap then function immediately exits, losing any reference to the object. This is a memory leak
void createObject()
{
int* x = new int;
}
int prompt()
{
int response;
std::cout << "Run again?\n";
std::cin >> response;
return response;
}
int main()
{
while(continue)
{
createObject();
// Running the program again and again will exacerbate the memory leak.
continue = prompt();
}
return 0;
}
Correct way to retain object reference in this contrived and useless example:
int* createObject()
{
int* x = new int;
return x;
}
int main()
{
// Pointer to the object created in the function in this scope is created, so we still have access to the variable.
int* a = createObject();
return 0;
}
Hope this helps, good luck in your class!
If you put some delay in the loop, you will be able to see the memory grow.
You can use sleep or wait for input from the user.
As it is now, the memory inflate so fast till you run out of allocation memory.
This is not a classic test of memory leak.
Memory leak it tested at the end of the program to see if you released all the memory.
I am a C++ beginner. And I am doing the exercises in C++ Primer (5th Edition). I found a reference to
Exercise 13.8 from Github (Here), which is shown below.
#include <string>
#include <iostream>
using std::cout;
using std::endl;
class HasPtr {
public:
HasPtr(const std::string &s = std::string()) : ps(new std::string(s)), i(0) { }
HasPtr(const HasPtr &hp) : ps(new std::string(*hp.ps)), i(hp.i) { }
HasPtr& operator=(const HasPtr &hp) {
std::string *new_ps = new std::string(*hp.ps);
delete ps; // I don't know why it is needed here?
// But when I delete this line, it also works.
ps = new_ps;
i = hp.i;
return *this;
}
void print() {
cout << *(this->ps) << endl;
cout << this->i << endl;
}
private:
std::string *ps;
int i;
};
int main() {
HasPtr hp1("hello"), hp2("world");
hp1.print();
hp1 = hp2;
cout << "After the assignment:" << endl;
hp1.print();
}
What makes me confusing is the HasPtr& operator=(const HasPtr &hp) function. I don't know why delete ps; is needed here. I thought it was an error, but it worked when I compiled the code. However, it also works when I delete the line of delete ps;. So, I do not know whether delete ps; is needed and what is the advantage if it is reserved.
HasPtr::ps is an heap-allocated std::string pointer.
It is allocated and constructed using new in all HasPtr constructors. Therefore, when HasPtr::ps gets replaced by another heap-allocated pointer, the existing memory has to be released using delete to avoid memory leaks.
Note that, in modern C++, you should almost never use new and delete for managing objects like this. Use smart pointers instead, like std::unique_ptr or std::shared_ptr, which take care of memory management for you, safely and conveniently.
I still suggest getting familiar with new and delete, as an huge amount of existing code makes use of them. cppreference.com is a great place to find detailed information about the language.
As Jan Hudec mentioned in the comments, it is generally pretty silly to store an std::string on the heap - std::string is a wrapper around an heap-allocated character array, which already manages the memory for you.
It's needed to prevent a memory leak: every new must be balanced with a delete.
You allocate memory for ps with a new in the constructors.
When you allocate memory for new_ps and assign this to ps, you need to free the constructor-allocated memory before you lose the old pointer value.
You program will indeed "work" if you omit that line, but it will steadily consume more and more memory, until, eventually there is no more memory left.
Note that you have another memory leak: you need to create a destructor, and call delete ps in it.
As you can see, this is getting unduly complicated. Better still, ditch all this pointer stuff and use a std::string s as the member variable - it takes care of all the memory management for you.
The delete is needed to avoid a memory leak.
The line ps = new_ps; edits the address of ps to point somewhere else.
The memory that ps was previously pointing at still needs to be freed. The effects of removing this line are not instantly visible and the program will still 'work', but you have a memory leak.
Eg.
ps = address 0 with value 'f'; new_ps = address 1 with value 'g'
Now let ps = new_ps;
ps = address 1 with value 'g'; new_ps = address 1 with value 'g'
So address 0 is no longer something we can access, but it's not been freed either
In C++ programming, calling delete on a class object automatically invokes the destructor of the class.
In general practice, destructor holds the code to free up the resources i.e file pointers,deletion of objects created inside the class.This way, when you call delete on an object,the resources it allocated are freed up i.e given back to the system
If these resources are not freed up,the memory allocated for these resources will not be given back to the system.Every time your object gets called,you lose a certain portion of memory and over a period of time you would have lost a major chunk of memory.This is called as memory leak.
Thus when you call delete on an object,you ensure that the resources you acquired are released, provided you have done those operations in destructor.
I would like experts review on the following dynamic memory allocation process and suggest whether there are any memory leaks. Following code is not real code in use, but trying understand concept of memory allocations and de-allocation in different ways.
class ObjMapData
{
private:
int* itsMapData;
........
public:
ObjMapData();
~ObjMapData(){if(itsMapData!= NULL) delete[] itsMapData;}
ClearMemory() {if(itsMapData!= NULL) {delete[] itsMapData; itsMapData= NULL}}
.......
void SetMapData(int* ptrData) { itsMapData = ptrData;} // or should I use int*&ptrData??
int* GetMapData() const { return itsMapData;}
}
Now can I do the following without any memory leaks?
bool Function1(ObjMapData& objMyMap)
{
//populate the ptrData with some data values using many different ways
int* ptrData = new int[1000]; // usually a variable from binary file header
......................
objMyMap.SetMapData(ptrData);
//don't want to delete the memory yet
return true;
}
bool Function2(ObjMapData& objMyMap)
{
int* ptrData = objMyMap.GetMapData();
//do some work such as writing updated data into a binary file
}
bool Function3(ObjMapData& objMyMap)
{
//populate the data
bool bStatus = Function1(objMyMap);
int* ptrData = objMyMap.GetMapData();
//update the map data using ptrData variable
..........
bStatus = Function2(objMyMap); // write data to a binary file
objMyMap.ClearMemory(); // not real code in use, but for understanding the concept
bStatus = Function1(objMyMap); // re-allocate memory
ptrData = objMyMap.GetMapData();
//update the map data using ptrData variable
objMyMap.SetMapData(ptrData); // Do I need to set again or member pointer get updated automatically?
return true
}
int main()
{
ObjMapData objMyMap;
bool bStatus = Function3(objMyMap);
//default destructor of objMyMap can take care of the allocated memory cleanup
return 0;
}
Thank you for your time to confirm the dynamic memory allocation..
Although this may seem to be more to do with style than your question about memory leaks, I would handle the data privately within the class:
class ObjMapData
{
private:
int* itsMapData;
// consider adding 'datasize' member variable
........
public:
ObjMapData(){ itsMapData=NULL; }; // initialise member variable(s)!
~ObjMapData(){ delete[] itsMapData;}
ClearMemory() { delete[] itsMapData; itsMapData=NULL; }
.......
void CreateMapData(int size) { ClearMemory(); itsMapData= new int[size]; }
void FillDataFrom( ???? ) { ???? };
int* GetMapData() const { return itsMapData;}
}
You are then in a better position to improve the class by adding copy constructor and assignment methods which will prevent memory leaks when you use the class.
EDIT
You ask:
My concern here is which of the following is right: void
SetMapData(int* ptrData) Vs void SetMapData(int*&ptrData)
Both are 'right' in the sense that both allow the external (to the class) pointer to be copied and used within your class - with respect to 'memory leaks' it depends on which part of your code you want to manage the memory you allocated. You could:
Have a class handle allocation/deallocation internally
Allocate memory, use some class to manipulate it, deallocate memory outside class
Have a class allocate memory and later deallocate it outside the class
Allocate memory and have some class manipulate and deallocate it.
Usually I find 1 and 2 make more sense than 3 or 4. i.e. it is easier to follow what is going on, less likely to hide errors and so on.
However, as far as 'leaking memory' is concerned: it does not matter where the pointer to an allocated memory block is, how it has been copied, assigned or referenced - it is it's value as a memory address which is important. So, as long as you new and delete that memory address correctly you will not leak memory (whether those actions are inside a class or not).
If, in your application, you need to allocate/deallocate the int array external to your class, it does make some sense for the member functions reference the pointer as a hint to the reader that the class is not responsible for its deallocation - but some decent comments should make that clear anyway :)
Over the years I've come across umpteen bugs due to the mishandling of the "passing of ownership" of allocated memory (more so with good ol 'C') where some piece of code has been written assuming either that it has to free a block or someone else will do it.
Does that answer your question or have I missed the point?
i saw some code like below, but i didn't see any delete statement, is there any memory leak problem?
struct RStatus
{
int fid;
int status;
};
void Foo()
{
vector<RStatus*> rsVec;
RStatus* rs = null;
rs = new RStatus(); // memory allocated here!
rs->fid = 0
rs->status = 0;
rsVec.push_back(rs);
}
If you use vector<RStatus*>, then you have to use delete, otherwise you will have a memory leak.
However, if you use vector<RStatus>, then you don't have to use delete — this is recommended1.
1. If you want to use pointers, then the recommendation is that you should be using smart pointers such as std::unique_ptr, or std::shared_ptr.
Yes, you should free your memory allocated :
struct RStatus
{
int fid;
int status;
};
void Foo()
{
vector<RStatus*> rsVec;
RStatus* rs = null;
rs = new RStatus(); // memory allocated here!
rs->fid = 0
rs->status = 0;
rsVec.push_back(rs);
// free :
unsigned int size = rsVec.size();
for (unsigned int i = 0; i < size; i++ )
delete rsVec[i]; // delete because you used new
}
If you don't do that, all the memory will never be released at the vector destruction.
I would suggest you to use std::vector<RStatus> instead of std::vector<RStatus*>.
You may also used smart ptr. You can found some documentation about it here : http://www.cplusplus.com/reference/memory/shared_ptr/
EDIT: As suggested in comments, if an exception is thrown at rsVec.push_back(rs), the memory allocated will be lost, that's why smart pointers would be a better solution. Or again, use std::vector<RStatus> instead.
Yes, there is a memory leak: the pointer to the created structure is lost after the vector is destroyed, and the memory is never released.
Unless someone performs a delete for each element of rsVec before clearing or destroying the vector.
Yes, that code leaks the RStatus.
It also does nothing else: possibly the real code's vector gets passed to some function that takes posession of the vector's contents.
Tracking down memory leaks is generally not a local problem: every use of that pointer has to, in theory, be examine to figure out if it leaks. Techniques like 'if I allocate it, delete it' and RAII (including smart pointers) attempt to make it more local, so you can tell from an incomplete program if there is a leak.
use boost::shared_ptr if you don't want to bother yourself with a deletion of allocated objects.
http://www.boost.org/doc/libs/1_54_0/libs/smart_ptr/shared_ptr.htm
struct RStatus
{
int fid;
int status;
};
void Foo()
{
vector<shared_ptr<RStatus> > rsVec;
shared_ptr<RStatus> rs = shared_ptr<RStatus>(); // empty shared_ptr
rs.reset(new RStatus()); // memory allocated here!
rs->fid = 0
rs->status = 0;
rsVec.push_back(rs); // shared_ptr is copied
}// vector is destroyed and shared_ptrs also
be careful however not to mixed up things using both shared_ptr and ordinary, raw pointers to avoid situation when shared_ptr tries to delete object which is already deleted
I heard a lot of memory leak vulnerability, but I could not find a real work example of memory leak, could you provide a real work example of memory leak, maybe of some big open source project and explain the solution to me
thx.
It's really simple actually. In your main put:
char* c = new char[4];
Then exit. That's a memory leak. Any new that doesn't get followed by delete is a leak.
This answer has some good examples, but like my comment has said, it will be fairly hard to find a released application with a leak that an outside observer can look at and easily identify.
I am screaming, cursing and yelling everyday about code like this in our (huge) legacy code base:
// returns raw pointer with changing conventions who's the owner...
HelpFoo* Foo::GetFoo(Bar* pBar, OtherFoo* pFoo)
{
// all 'local' variables even those allocated on freestore declared
// and initialized in a large block at the beginning of the function/method
HelpFoo *A = new HelpFoo;
OtherHelpFoo *B, *C;
EvenMore *D = new EvenMore;
// and so on, these blocks can be huge...
// a complicated spaghetti code in here, with dozens of nested 'ifs'
if (/* some expression */) {
} else if (/* some other expression */) {
// and so on... then suddenly:
if (/* some other nested expression */) {
// I forgot that I've allocated other memory at the beginning...
return A;
}
}
// some miserably written logic here and suddenly
if (D) delete D; return A;
// call to some other function with cryptical name without any
// kind of knowledge what happens with the resource:
FooTakesReferenceToPointer(&A);
// suddenly returning something completely different
// what should I free, A, D...?
return C;
}
I tried to write in comments what the problems are. Clearly, forget about exceptions. The spaghetti code is so bad that nobody can tell what the logic actually is. Therefore it is really, really easy to forget to free memory and that happens very, very frequently. Solution 1: Throw away and rewrite everything. Solution 2: Keep spaghetti as it is, replace all newed resources by smart pointers and make_shared or make_unique, let compiler yell. Of course, first write a test suite (which didn't exist before) to guarantee the same (often screwed) behaviour for all possible sets of inputs (which are not documented).
EDIT
As james said this is undefined behaviourso no promises
You could do something like this:
#include <vector>
class Base
{
public:
Base()
{
baseData = new char [1024];
}
~Base()
{
delete [] baseData;
}
private:
char* baseData;
};
class Derived : public Base
{
public:
Derived()
{
derivedData = new char[1024];
}
~Derived()
{
delete [] derivedData;
}
private:
char* derivedData;
};
int main()
{
std::vector<Base*> datablocks;
datablocks.push_back(new Base());
datablocks.push_back(new Derived());
for(unsigned int i = 0; i < datablocks.size(); ++i)
{
delete datablocks[i];
}
datablocks.clear();
return 0;
}
The data in the Derived class wont be removed here since we are calling delete on a Base* and the Base class does not declare a virtual destructor.
A lot examples could be given here. Just allocate some memory and do not free it.
A good example for this would be the following:
char* pBuffer = new char[ 1024 ]; // or something else, dynamically allocated
// do something here
// now suppose, calling f() throws
f();
// do some other things
delete[] pBuffer;
When f() throws, if the exception is not caught, delete[] will never be executed. Thus, memory leak.
This is one of the best examples why smart pointers should be used.
Another example would be - a function, returning pointer to dynamically allocated memory. The user, often, may forget to free this memory. Something like:
char
char* f()
{
return new char[ 1024 ];
}
//...
// in some other function
char* pSomething = f();
// do some stuff here and return
Imagine you're processing network data and create polymorphic "message objects" based on the data:
while (true)
{
char buf[1024];
size_t len = read_from_network(buf, 1024); // fictitious, for demonstration only
Message * p = Message::Parse(buf, len); // allocates new, dynamic, concrete object
engine.process(p);
}
The engine object may chose to store the object somewhere and use it again later, and if nobody takes care of deleting it, you have a perfect leak.
While the other answers give enough hints, some 'real world' memory leaks which I have seen in our applications.
I don't remember if this was found before or after the release, but, I guess that doesn't matter.
void f()
{
BYTE* b = NULL;
f = open a file;
while (!f.end())
{
int size = getNextRecordSize(f);
b = new BYTE;
readNextRecord(f,b);
process record;
}
delete b;
}
Bit hard to detect this. The reviewers might take it for granted that the memory is deleted properly by seeing the delete call. However, it deletes only the memory allocated for the last record. Rest is leaked.
class A
{
public:
BYTE* get()
{
allocate a new buffer, copy the someData buffer and return that.
The client is expected to delete it
};
private:
BYTE* someData;
};
void f()
{
A a;
B.initialize(a.get()); // It is so convenient to use the pointer. It is not obvious from the function name
// that the result of get has to be deleted.
}
One example I often run across in our code is in image understanding functions, where a temporary 8bit memory is allocated, and never released (yeah, I know, when you do a new, do a delete right afterwards...)
unsigned char* dataToBeUsed = new unsigned char[imgsize];
memcpy(dataToBeUsed, original, imgsize);
// use and process the data here
return value;
The allocated memory is never released -> memory leak. Windows will kill the memory when the application is exited completely, but before that within the application that memory is just lost -> leaked.
A memory leak occurs when the programmer has the memory leak of forgetting to free allocated memory :-)
linebuffer = new char[4096];
/* do things */
/* forget to free memory */
Normally, if you cause a memory leak and then exit the program, it is not harmful, since the operating system normally frees the resources allocated by the program. The problem arises when your application runs for a long period of time (for example, a service). If your program causes memory leaks, then you will run out system's memory, unless the operating system has mechanisms to avoid that; in such case, it will terminate your program.
So, be careful and eat fish: it's very good for memory :-)
To give you a real-world example, a bit of googling turned up this memory leak in 389 Directory Server (a RedHat Open Source product).
Just lose the pointer to dynamically allocated memory:
void foo()
{
int *arr = new int[100];
}