Help identifying memory leak - c++

I have a class here that is defined like this:
struct USERFPOINT
{
POINTFLOAT UserPoint;
POINTFLOAT LeftHandle;
POINTFLOAT RightHandle;
bool isBezier;
};
struct SHAPEOUTLINE {
GLuint OutlineVBO;
int OutlineSize;
int OutlineWidth;
ARGBCOLORF OutlineColor;
};
struct SHAPECONTOUR{
std::vector<USERFPOINT> UserPoints;
std::vector<std::vector<GLdouble>> DrawingPoints;
SHAPEOUTLINE Outline;
};
struct SHAPEGRADIENT{
GLuint TextureId;
bool IsParent;
bool active;
int type;
std::vector<ARGBCOLORF> colors;
};
struct SHAPEDIMENSIONS {
POINTFLOAT Dimensions;
POINTFLOAT minima;
POINTFLOAT maxima;
};
class OGLSHAPE
{
private:
int WindingRule;
GLuint TextureCoordsVBOInt;
GLuint ObjectVBOInt;
UINT ObjectVBOCount;
UINT TextureCoordsVBOCount;
SHAPEGRADIENT Gradient;
SHAPEDIMENSIONS Dimensions;
void SetCubicBezier(USERFPOINT &a,USERFPOINT &b, int &currentcontour);
void GenerateLinePoly(const std::vector<std::vector<GLdouble> > &input, int width);
public:
std::string Name;
ARGBCOLORF MainShapeColor;
std::vector<SHAPECONTOUR> Contour;
OGLSHAPE(void);
void UpdateShape();
void SetMainColor(float r, float g, float b, float a);
void SetOutlineColor( float r, float g, float b, float a,int contour );
void SetWindingRule(int rule);
void Render();
void Init();
void DeInit();
~OGLSHAPE(void);
};
Here is what I did as a test. I created a global std::vector<OGLSHAPE> test .
In the function I was using, I created
OGLSHAPE t.
I then pushed 50,000 copies of t into test.
I then instantly cleared test and used the swap trick to really deallocate it.
I noticed that all the memory was properly freed as I would expect.
I then did the same thing but before pushing t into test, I pushed a SHAPECONTOUR (which I had just created without modifying or adding anything into the contour) before pushing t into test.
This time after clearing test, 3 more megabytes had been allocated. I did it again allocating twice as many and now 6MB we remaining. The memory usage of the program peaked at 150MB and it went down to 12MB, but it should be at 8.5MB. Therefore, this must be classified as a memory leak, although I do not see how. There is nothing that I see that could do that. SHAPECONTOUR is merely a structure of vectors with a nested structure of vectors.
Why would this cause a leak, and how could I fix it?
Thanks

If you've deleted everything, there is no leak, by definition. I don't see any unwrapped pointers, ergo everything gets deleted. Therefore, you have no leaks.
Likely, the OS has simply decided to leave that memory available to your program, for whatever reason. (It hasn't "reclaimed" it.) Or maybe it needs to allocate in groups of4MB, and so going from 12MB to 8MB wouldn't leave enough required memory. Or...
You're cutting out other reasons entirely; you should use a real memory leak tool to find memory leaks.

When you allocate large chunks of memory, the CRT keeps some of it around for when you need to allocate again. You can't use Task Manager to indicate leaks.
If your class uses self-clearing members like vector, they do not leak memory.

How about explicitly clearing the vectors of SHAPECONTOUR in the destructor of OGLSHAPE? Rerun your test with this & check if you still have the observed leak.

How are you clearing that vectors? Try using in destructors something like this:
std::vector<SHAPECONTOUR>().swap(Contour);
And do the same with other vectors from your code(UserPoints, DrawingPoints, colors).

I would suggest to use a leak detection tool to find out if you really have a leak. For example for Windows dev you can use Visual Leak Detetor (VLD).
If you do indeed have a leak then it is probably not where you think it is.
Also you may just be wrong in that there is no leak at all. For example if you are looking just at the stats via something like task manager, this does not mean there is a leak in your program. The OS that runs your program is a separate beast than the programming language that you may have a leak inside of. I.e. the OS can take longer to reclaim freed memory.
Edit:
If you want to make sure the vector has capacity 0 it is pretty common to do the following:
v.swap(std::vector<char>());
assert(v.capacity() == 0);

What debugging tools did you use? Try yet deleaker! it is simple!

Related

C++ allocating dynamic memory in one function and clearing another function

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?

If I assign a POD struct to another POD struct, is there any memory leak?

For example:
struct Vertex
{
int x;
int y;
};
Vertex makeVertex(int xpos, int ypos)
{
Vertex tmp = {xpos, ypos};
return tmp;
}
Would I get a memory leak if I did this?:
Vertex a = makeVertex(30,40);
a = makeVertex(5, 102);
This is perfectly safe.
Memory leaks are caused by (mis)using pointers and memory allocations (typically calls to new that aren't followed by calls to delete, but more complex cases are often where the real problems occur - e.g. not completing the "rule of three (or five)" when dealing with classes that have calls to new).
And of course when using the C style calls to malloc and siblings the code should have a corresponding free call.

C++ vector of struct with vector in struct causing exception

I got a problem with the following code, which I can't solve since hours...
I'm glad for any kind of advice.
The types are defined as follows:
typedef std::vector< cv::RotatedRect > ds_t;
typedef struct id_ {
std::string path;
std::string fileName;
} id_t;
typedef struct dd_ {
cv::RotatedRect bB;
} dd_t;
typedef std::pair<id_t, std::vector<dd_t> > ts_t;
typedef std::vector<ts_t> tss_t;
Then I try to fill the type with data:
tss_t samples
while (readdir(pDir) != NULL) {
ts_t sample;
sample.first.path = _path;
sample.first.fileName = _name;
ds_t detections;
getDetections(_path, detections); //this only filles the detecions byref
for(size_t i=0; i<detections.size(); i++) {
dd_t data;
data.bB = detections[i];
sample.second.push_back(data); //TODO FIXME
}
samples.push_back(sample);
}
cv::RotatedRect is a very basic class.
class RotatedRect{
public:
RotatedRect();
RotatedRect(const Point2f& _center, const Size2f& _size, float _angle);
void points(Point2f pts[]) const;
Point2f center;
Size2f size;
float angle;
};
bool getDetections(const std::string &imagePath, ds_t &detections)
{
//some processing
for(size_t i=0;i<5;i++)
detections.push_back(RotatedRect(cv::Point2f(110.,110.), cv::Size2f(10.,10.), 90.0f));
return true;
}
Hopefully I copied the whole code and I know, I don't need most of the typedefs...
I have already tried to reserve space sample.second.reserve(detections.size()), but this only postpones the error to samples.push_back.
The erroneous line is indicated by the FIXME, causing "terminate called after throwing an instance of 'std::bad_alloc'"
Thanks for any advice in advance.
std::bad_alloc generally means that you've run out of memory -- possibly because of a leak, or just because you've allocated too much. It can also (rarely) happen due to heap corruption (running off the end of an allocated array or dereferencing a pointer after it has been deleted) or other undefined behavior at some earlier point in the program.
How much memory is your program trying to use at one time? You can try using a leak detector like valgrind to see if there is stuff you should be cleaning up.
edit
The -1 to __builtin_new tells you a lot -- it tells you that someone is calling new with a bogus size. That would probably be a member of std::vector that tries to resize things (you can check the stack trace from valgrind or use a debugger to be sure), which indicates that the vector has been corrupted. Since sample.second is a local (on stack) variable, that tells you that a previous function you called (probably getDetections) overran an onstack buffer or array of some kind and clobbered sample.second. So take a careful look at what that function is doing -- the code you've commented out as //some processing. You can also try using a debugger to set a breakpoint just after sample is created and then set a watchpoint on the memory used by sample.second that is getting corrupted. Then continue the program and it should stop at the point that is clobbering sample.second
It may be helpful to read your compiler's header files to figure out how it implements std::vector -- there's probably a couple of size_t fields and a pointer field in there.

C++ adjacency list of pointers and structs

Working on adjacency list --> directed weighted graph
One class looks like this, i.e. header:
class CGraph;
class CMap {
public:
//voided constructors and destructors
//functions one is:
void SetDirGraph(string commands);
private:
CGraph* m_myMap;
};
Second class:
class CNode {
public:
//voided constructor and desctructor
int m_distance, m_vert;
bool m_isKnown;
};
typedef struct edges {
int v2, weight;
} edge;
class CGraph {
public:
CGraph(int map_size);
~CGraph(void);
void AddMap(int v1, int v2, int weight);
void AddEndVert(int v2, int weight);
private:
list<edge> List;
int size;
public:
CNode* verts;
};
I'm reading vertices from a file, and that works. My problem is I am having trouble creating an adjacency list based on the code given. I'm trying to use pointers first that points to a list and it is not working correctly. I don't know how to create my pointers to the list without writing over them.
void CMap::SetDirGraph(string command) {
istringstream buffer(command)
char ch;
int num, vert1, vert2, weight; //specify vertices and weight and number of vertices
buffer>>ch; //throw away first character (not needed)
buffer>>num // size of vertices
while(!buffer.eof()) { // keep reading until end of line
buffer>>v1; // vertex start
buffer>>v2; // vertex end
buffer>>weight;
m_myMap = new CGraph(map_size); //initialize m_myMap.
m_myMap->verts->m_vert = v1; // mymap->verts->vert points to first edge
m_myMap->AddMap(v1, v2, weight); // create list?
m_myMap->AddEndVert(v2, weight); //create list? push v2 and weight on my list using my list.
}
}
I've tried several different ways and I keep confusing myself, any point in the right direction would be awesome.
EDIT:
I have more code too if needed to be produced, just publishing the main stuff.
What I mean by "not working" is that I am just writing over the previous vertex. I don't know if I should create an array using m_myMap (tried and still writes over and get a memory error as well). No compiler errors.
I don't know how to create my pointers to the list without writing over them.
Apart from your application, the answer to this question is the new operator, which I assume you are aware of, since you used it within your example code. Code like int * a = new int(42); allocates memory for an int on the heap and you are responsible for cleaning it up when it is not needed anymore. You thereby have full control over how long a variable will be available. In int x = 42; int * a = &x; on the other hand, x will automatically be cleaned up when it runs out of scope, and a will be a pointer to a memory block that has no meaningful data in it anymore. If you try to dereference it, you will encounter undefined behavior, and, if you are lucky, your program will blow up.
If you can use the C++11 standard, or a library that offers smart pointers, you should prefer those over managing the pointer yourself whenever possible. A smart pointer is an object that holds the allocated memory and frees it automatically when it is destructed. More specific information depends heavily on which sort of smart pointer you are using. The reason for using smart pointers is that doing the management yourself is tedious and error prone. If you do not delete your pointers you had allocated, your application will keep on allocating more memory until it blows up some day (depending on how often and how much memory you allocate); this is called leaking. If you call delete more than once, your program will bail out as well. Here is an example of C++11 shared_ptr in your application:
class CMap
{
private:
std::shared_ptr<CGraph> m_myMap;
// etc.
};
// in SetDirGraph
m_myMap.reset( // if the smart pointer has previously been managing
// memory, it will free it before allocating new
new CGraph(map_size) // allocate CGraph as before
);
Besides that, what hopefully answers your question, I have run into several potential problems concerning your code:
Definitely wrong:
In SetDirGraph you set m_myMap->verts->m_vert = v1. m_myMap->verts is a pointer. You have freshly created m_myMap and thus verts is not initialized, hence pointing at a random block of memory. You then try to dereference it by m_myMap->verts->m_vert = v1. This cannot work. You need to create verts first, i.e. verts = new CNode;.
typedef struct edges { /* etc */ } edge; is a C construct and there is no need for the typedef wrapper in C++. It does work and all, but it is really redundant and lots of those constructs just pollute the namespace you are working in.
Do you really need pointers in the first place? Your provided snippets do not hint at why you would need to use them. You will want to reduce usage of pointers to a minimum (or at least use smart pointers, see above)

How to create a memory leak in C++?

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