?
Solved

ensuring statically allocated memory is destroyed

Posted on 2006-04-18
13
Medium Priority
?
255 Views
Last Modified: 2010-04-01
I have some BYTE* buffer's defined statically in my camera class (for performance reasons)

BYTE* CMyCamera::m_pTempFrameBuffer      = new BYTE[iHeight * iWidth];            // 8bit buffer for raw data
BYTE* CMyCamera::m_pBuffer      =  new BYTE[iHeight * iWidth * iByteStep];      // 24bit buffer for RGB converted data

So these arrays are created, even if CMyCamera is never instantiated.  In the cases where CMyCamers is instantiated, I delete[] and NULL out those buffers in the destructor.

But there are cases where my app never instantiates CMyCamera (if the user never uses it) - so howthen do I ensure they are destroyed to prevent the memory leak?

ie. how do I destroy statically allocated memory like that?

thanks!
0
Comment
Question by:PMH4514
  • 3
  • 3
  • 3
  • +3
13 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 400 total points
ID: 16482099
When your program exits, the memory will be freed anyway.

But, you could use a helper class like e.g.

BYTE* CMyCamera::m_pTempFrameBuffer     = new BYTE[iHeight * iWidth];          // 8bit buffer for raw data
BYTE* CMyCamera::m_pBuffer     =  new BYTE[iHeight * iWidth * iByteStep];     // 24bit buffer for RGB converted data

struct CMyCameraCleanupHelper {

CMyCameraCleanupHelper () {}
~CMyCameraCleanupHelper () {

delete [] CMyCamera::m_pBuffer;
delete [] CMyCamera::m_pTempFrameBuffer;

}

};

CMyCameraCleanupHelper g_hlp;

0
 
LVL 30

Assisted Solution

by:Axter
Axter earned 200 total points
ID: 16482189
If you're accessing these buffers via global object's destructor, it's better if you don't delete the buffer at all.

>>even if CMyCamera is never instantiated.
You could avoid creating the buffer when it's not needed by putting it in a static function.
Example:
BYTE* CMyCamera::get_pTempFrameBuffer()
{
   static BYTE* pTempFrameBuffer     =  new BYTE[iHeight * iWidth];  
   return pTempFrameBuffer;
}

If this function is never called, then the buffer is never crated.
0
 
LVL 11

Expert Comment

by:Deepu Abraham
ID: 16482251
To delete the buffer you can try checking the buffer pointer.

like,

if( ptrBuffer!=NULL)
{
 delete [] pTempFrameBuffer;

}

Best Regards,
Deepu
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 11

Expert Comment

by:Deepu Abraham
ID: 16482270
Sorry,

Its a copy paste error :(

To delete the buffer you can try checking the buffer pointer inside the destructor.

like,

CMyCamera:: ~CMyCamera()
{
  if( ptrBuffer!=NULL)
 {
  delete [] ptrBuffer;
 }

}

Best Regards,
Deepu
0
 
LVL 30

Expert Comment

by:Axter
ID: 16482285
>>To delete the buffer you can try checking the buffer pointer.

There is no need to check the buffer pointer.
IAW C++ standard you can call delete on a NULL pointer, so delete is already performing this logic.
By adding an extra check, it just makes the code less efficient, and adding un-needed code.

Instead, just call delete directly.
delete [] pTempFrameBuffer; //No pre-check for NULL
0
 
LVL 2

Expert Comment

by:bachra04
ID: 16482611
Hi,

your buffer is not statically allocated, it is dynamically allocated at the heap memory,  so you need to destroy it using delete[].
The right way to do that is to delete it when you don't need it anymore at the correct point. So if you allocate the buffer at the constructor then you need to delete it at the destructor but if it is allocated at the start of the program i.e globally, then you need to destroy it at the end of the program.
I think if the performance is your issue the best way is to declare the buffer at the stack memory like this you don't have any problem with memory :
const int MAX_SIZE = 1000;

BYTE CMyCamera::m_pTempFrameBuffer [MAX_SIZE ];          

B.T
0
 
LVL 1

Assisted Solution

by:i_mahesh
i_mahesh earned 200 total points
ID: 16484815
Hi,
there are may approaches you can take to tackel this issue:

There are two conditions
a. You know the size of the buffer to be allocated at compile time
b. You will get to know the size of the buffer only after you start running the program.

in case a. the best option would be to take the approach suggested by bachra04 ie.
you can allocate the memory on the global / static stack instead of dynamically creating the buffer at run time provided the size of the buffer is known at compile time.

in case b. you have the following options;

1. As suggested by jkr.
2. you can initialize the static buffer pointers to NULL and allocate memory in the constructor when forst object instance of the class is created and delete the buffer when last instance of the object is being destroyed. for this approach you need to do reeference counting, for which you can include a static member in your class which will keep the track of numbers of instances of the class you.

the things will look some thing like this:

class CMyCamera
{
public:
    CMyCamera()
   {
       if (m_cRef == 0)
       {
            m_pTempFrameBuffer     = new BYTE[iHeight * iWidth];
            m_pBuffer     =  new BYTE[iHeight * iWidth * iByteStep];
        }
        m_cRef++;
   }

    ~CMyCamera()
   {
       m_cRef--;
       if (m_cRef == 0)
       {
            delete [] m_pTempFrameBuffer;
            delete[] m_pBuffer;
            m_pTempFrameBuffer = NULL;
            m_pBuffer = NULL;
        }
    }

static BYTE* m_pTempFrameBuffer;          // 8bit buffer for raw data
static BYTE* m_pBuffer;     // 24bit buffer for RGB converted data
static UINT m_cRef;
};

BYTE* CMyCamera::m_pTempFrameBuffer     = NULL;          // 8bit buffer for raw data
BYTE* CMyCamera::m_pBuffer     =  NULL;     // 24bit buffer for RGB converted data
UINT CMyCamera::m_cRef = 0;   //Reference count for the class

0
 

Author Comment

by:PMH4514
ID: 16487990
interesting stuff.

I do know the sizes required at compile time. I used to allocate the memory on the non-static members in the constructor and delete it in the destructor. worked just fine. I noticed some performance improvements when I defined them as static and allocated the memory "statically" (that is, at the top of my class, outside the code block, I called the new BYTE .....) though I admit I don't fully understand why there would be a performance improvement.

my thinking is that "these sizes are fixed, and known at compile time. how can I best setup the buffers for use and ensure they're deleted on program exit"
0
 
LVL 30

Expert Comment

by:Axter
ID: 16488021
>>I best setup the buffers for use and ensure they're deleted on program exit"

You don't need to.  On program exit, the buffer is release automatically.
0
 

Author Comment

by:PMH4514
ID: 16488289
>>On program exit, the buffer is release automatically.

ok that's what I thought. I was seeing the IDE show memory leaks on those two buffers though, but that was on abnormal program termination.
0
 
LVL 2

Expert Comment

by:bachra04
ID: 16488339
If you know the size at compile time why you allocate the buffer using NEW, I don't think it is a good practice, in addition it makes your program heavier (more heap memory used).

B.T

0
 

Author Comment

by:PMH4514
ID: 16488585
>>why you allocate the buffer using NEW, I don't think it is a good practice,

what is the appropriate alternative?
0
 
LVL 2

Expert Comment

by:bachra04
ID: 16488698
You need to declare a static array like this:

in the class definition declare a static array member with a fixed size.

const unsigned int  MAX_SIZE = 1000;
Class Camera
{

public:

//....

static Byte m_FrameArray[MAX_SIZE];

}

like this your array will be allocated at compile time and not at run time, this improves performance and avoid you any memory problems.
0

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
Suggested Courses

864 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question