?
Solved

How to handle pointers to pointers C++

Posted on 2011-04-28
12
Medium Priority
?
421 Views
Last Modified: 2012-05-11
I was wondering what is the correct to handle pointers to pointers, that is passing them into a function and delete them on return if the function receiving the pointers creates the memory but does not release it.

Say I have some code as below:
char *pInBuff;

ReturnData(char** pData);

Where ReturnData is defined something like:
ReturnData(&pInBuff)
{
     *pInbuff = new char[128];

     // load pInBuff with data
}

What is proper way to free pInBuff? Is it a simple delete pInbuff, delete [] pInBuff or something else?

Thanks
0
Comment
Question by:atomicgs12
  • 4
  • 3
  • 2
  • +2
12 Comments
 
LVL 33

Accepted Solution

by:
Todd Gerbert earned 2000 total points
ID: 35489118
Yes, delete [] pInBuff.
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 35489548
If you have a function that allocates the memory, I would create a corresponding function in the same compilation unit that de-allocates the memory.

Something like below.


Or better yet : since you're using C++, you could :

(a) make use of SQL data structures like std::string

(b) encapsulate the buffer in a class that has a destructor that takes care of cleaning up the memory automatically

Either of the latter two are preferred over the example below.
void getData(char** pInBuff) {
    *pInbuff = new char[128];

    // load pInBuff with data
}

void cleanData(char** pInBuff) {
    delete [] *pInBuff;
    *pInBuff = 0;
}

// and then :

char* inBuff = 0;
getData(&inBuff);
// use inBuff ...
cleanData(&inBuff);

Open in new window

0
 
LVL 9

Expert Comment

by:Orcbighter
ID: 35490060
To make it a little clearer, wrap the whole thing in a class and then pass an instance of the class around


// file MyBuffer.h
class MyBuffer
{
private:
   char* m_buffer = NULL;

protected:
   void Empty();
   
public:
   MyBuffer();
   ~MyBuffer();
   
   void CleanData();
 }

 // file MyBuffer.cpp
MyBuffer::~MyBuffer
{
    Empty();
}

MyBuffer::Empty()
{
    if ( m_buffer != NULL )
    {
        delete [] m_buffer;
        m_buffer = NULL;
    }
}

MyBuffer::CleanData()
{
     Empty();
}

bool MyBuffer::IsEmpty()
{
    return ( m_buffer == NULL )
}

bool MyBuffer::LoadData( const char* data )
{
    bool retStatus = false;
    
    if ( IsEmpty() )
    {
        if ( data != NULL ) && ( strlen( data ) > 0 )
        {
            m_buffer = new char[strlen( data ) + 1];
            retStatus = true;
        }   
    }
    
    return retStatus;
}

// in file using this class

// on stack
{
    MyBuffer buff;
    char* TestData = "This is test data";

    buff.LoadData( TestData);
}

// or on heap
{
    MyBuffer buff = new MyBuffer();
    char* TestData = "This is test data";

    buff->LoadData( TestData);
    delete buff;
}

Open in new window

0
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
LVL 9

Expert Comment

by:Orcbighter
ID: 35490071
opps a little too quick
last bit should read

// in file using this class

// on stack
{
    bool AllOK = true;
    MyBuffer buff;
    char* TestData = "This is test data";

    ALLOK = buff.LoadData( TestData);
    if ( ALLOK )
    {
        // success
    }
    else
    {
        // error
    }
}

// or on heap
{
    bool AllOK = true;
    MyBuffer buff = new MyBuffer();
    char* TestData = "This is test data";

    AllOK = buff->LoadData( TestData);
    if ( ALLOK )
    {
        // success
    }
    else
    {
        // error
    }

    delete buff;
}

Open in new window

0
 
LVL 35

Expert Comment

by:sarabande
ID: 35490113
why not simply use std::vector?

std::vector<char> v;
getdata(v);
...
void getdata(std::vector<char> & v)
{
    v.resize(128, ' '); // 128 space characters
}

Open in new window


you don't need care for allocation or deallocation yourself. and the called function freely can increase the buffer as needed. and if you need a char* pointer you get it by &v[0] (only if v.size() > 0).

Sara
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 35490126
Wow - just noticed a typo in my previous post :

>> (a) make use of SQL data structures like std::string

STL of course, not SQL hehe.
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35490334
Hmm, perhaps I read the question too literally. ;)
0
 

Author Comment

by:atomicgs12
ID: 35492476
tgerbert - Are you second quessing yourself? I appreciate all the cool solutions from everyone but I was just looking for something simple and straight forward.

delete [] pInBuff; should be fine, yes?
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35493647
Then in that case, yup, delete [] pInBuff. Though I do like Infinity's comment.
0
 

Author Comment

by:atomicgs12
ID: 35493840
as per Infinity's solution:
a. I need this to be Unicode so std:string is out
b. The user may what to keep the data around even after the object that allocated it is destroyed

Thanks to all
0
 
LVL 33

Expert Comment

by:Todd Gerbert
ID: 35494043
a: std::wstring

b: the caller can control the lifetime of the data by controlling the scope of the object
0
 
LVL 53

Expert Comment

by:Infinity08
ID: 35508351
>> a. I need this to be Unicode so std:string is out

Your current approach of using a char* would be out too ;)
This remark also doesn't invalidate the point I was trying to make ... which was that you have several options that are better than your current approach. One of them is to use an existing solution (whether that be std::string or something else).


>> b. The user may what to keep the data around even after the object that allocated it is destroyed

As tgerbert said : if you want to keep the object, then keep it - nothing is forcing you to clean up the object at any other time than the time that you choose.
The point of encapsulating the buffer in a class, is to make your life easier, by hiding the memory allocation details from the calling code.
0

Featured Post

Free Backup Tool for VMware and Hyper-V

Restore full virtual machine or individual guest files from 19 common file systems directly from the backup file. Schedule VM backups with PowerShell scripts. Set desired time, lean back and let the script to notify you via email upon completion.  

Question has a verified solution.

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

Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
Whether you've completed a degree in computer sciences or you're a self-taught programmer, writing your first lines of code in the real world is always a challenge. Here are some of the most common pitfalls for new programmers.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

850 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