0

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..

  • 2
    `delete nullptr` is safe btw, you don't need the null checks. You have violated the rule of three though. What happens if I copy your object? Double delete. – Ed S. Mar 20 '14 at 18:01
  • 2
    I think your question is more appropriate for http://codereview.stackexchange.com/ – XiaoChuan Yu Mar 20 '14 at 18:03
  • Hi Ed, Can you please confirm whether SetMapData() function takes the copy or update the original source?? – user3442509 Mar 20 '14 at 18:05
  • What is hard about understanding memory allocations? You receive a pointer value to an allocated block of memory, then later on in the program, somewhere, somehow you take that same value that was returned to you and use it in the deallocation function. Simple. The problem arises when you lose that original value (like your program does in SetMapData), or you get tangled up in so many knots in your program that you forget to deallocate, deallocate the same pointer twice (or more times), or you deallocate a value that doesn't point to an allocated block. – PaulMcKenzie Mar 20 '14 at 18:17
  • Take a look at [What is The Rule of Three?](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – R Sahu Mar 20 '14 at 18:29
  • Thanks Paul. Which is right way to assign the data: void SetMapData(int* ptrData) Vs void SetMapData(int*&ptrData) – user3442509 Mar 20 '14 at 18:31
  • This question appears to be off-topic because it is asking for a code review, for which there is a dedicated StackExchange site: http://codereview.stackexchange.com. – Kaz Mar 20 '14 at 18:33
  • Hi Sahu, In my real code, yes I do follow Rule of Three to have all the three member functions (Destructor, CopyConstructor(), AssignmentOperator()) In the above example, my concern was after using SetMapData() kind of function, can the object default destructor clear the actual memory allocated? Or setMapData() is making a copy of the original pointer?? – user3442509 Mar 20 '14 at 18:46

1 Answers1

1

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:

  1. Have a class handle allocation/deallocation internally
  2. Allocate memory, use some class to manipulate it, deallocate memory outside class
  3. Have a class allocate memory and later deallocate it outside the class
  4. 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?

TonyWilk
  • 1,447
  • 10
  • 13
  • My concern here is which of the following is right: void SetMapData(int* ptrData) Vs void SetMapData(int*&ptrData) to mainly allow me to allocate memory and hence populate the data in different non member functions and de-allocate automatically in one destructor member function. Real code is 20000+ lines...and so trying to rise my concern with a simple example. Thanks – user3442509 Mar 20 '14 at 18:51