开发者

help with fixing memory leak

i have a member function in which i need to get some char array at run time

My fear

Is if i try

delete buffer;

then i cant

return buffer;

But how to i release the memory i allocated with

char * buffer= new char[size]

The class

class OpenglShaderLoader
    {      
    char * getLastGlslError()
    开发者_运维问答   {
             char * buffer;//i don't know the size of this until runtime
             int size;
             glShaderiv(hShaderId,GL_INFO_LOG_LENGTH,&size);//get size of buffer
             buffer= new char[size];
             //.. fill in the buffer

             return buffer;
       }
    }


You should return a std::vector<char>. That way, when the caller finishes using the vector, its contents are freed automatically.

std::vector<char> getLastGlslError()
{
    int size;
    glShaderiv(hShaderId, GL_INFO_LOG_LENGTH, &size);
    std::vector<char> buffer(size);
    // fill in the buffer using &buffer[0] as the address
    return buffer;
}


There is a simple adage - for every new there must be a delete, in your case, in relation to the class OpenglShaderLoader, when you call getLastGlsError, it returns a pointer to the buffer, it is there, that you must free up the memory, for example:

OpenglShaderLoader *ptr = new OpenglShaderLoader();
char *buf = ptr->getLastGlsError();
// do something with buf
delete [] buf;

You can see the responsibility of the pointer management rests outside the caller function as shown in the above code example/


You'd need another method, such as:

void freeLastGlslError(const char* s)
{
   delete [] s;
}

But since you're using C++, not C, you shouldn't return a char*. For an object-oriented design, use a string class that manages the memory for you, like std::string. (Here's the litmus test to keep in mind: if memory is being freed outside of a destructor, you're probably doing something inadvisable.)


Here's a trick how to do it:

class A {
public:
   A() : buffer(0) { }
   char *get() { delete [] buffer; buffer = new char[10]; return buffer; }
   ~A() { delete [] buffer; }
private:
   char *buffer;
}


When you return that pointer, whatever you're returning the pointer to should assume responsibility over that resource (i.e. delete it when done with it).

Alternatively, you can use a smart pointer to automatically delete the memory for you when nothing points to it.

Creating and returning a stl container or class (e.g. std::vector, std::string) is also a viable option.


Don't return a primitive char*. Encapsulate it in a class.

Assuming that the char array is really not a NULL terminated string, you need to include the size of it on return anyway. (It is sort of messy to continuously call glShaderiv to get the length, especially if it has performance implications. Easier to store the size with the allocation.)

Some have suggested using std::string or std::vector as the return. While each of these will work to a varying degree, they don't tell you what it is that is in each instance. Is it a string you print or is it an array of signed 8 bit integers?

A vector might be closer to what you need, but when you're looking at the code a year from now you won't know if the output vector of one method contains shader info when compared to another method that also returns a vector. There may also be implications of vector that make it undesirable for things like filling the buffer by passing a pointer to a device driver method since the storage is technically hidden.

So putting the return in a class that allocates your buffer and stores the size of the allocation allows you to let the return instance go out of scope and delete the buffer when the caller is done with it.


now body mentioned managed pointers yet?

If you don't need the features of a vector then ::array_ptr<char> might also help rather than rolling your own as in tp1's answer. Depending on version of compiler, available in boost/TR1/std.

boost::array_ptr<char> getLastGlslError()
{
    int size;
    glShaderiv(hShaderId, GL_INFO_LOG_LENGTH, &size);
    boost::array_ptr<char> buffer = new char[size];

    return buffer;
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜