帮助修复内存泄漏

help with fixing memory leak

本文关键字:泄漏 内存 帮助      更新时间:2023-10-16

我有一个成员函数,我需要在运行时得到一些字符数组

我的恐惧
如果我尝试

delete buffer;

那么我不能

return buffer;
但是如何释放我用 分配的内存呢?
char * buffer= new char[size]

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;
       }
    }

您应该返回一个std::vector<char>。这样,当调用者使用完vector容器时,vector容器的内容将自动释放。

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;
}

有一个简单的格言-对于每个new必须有一个delete,在您的情况下,与OpenglShaderLoader类有关,当您调用getLastGlsError时,它返回一个指向缓冲区的指针,它在那里,您必须释放内存,例如:

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

您可以看到指针管理的责任在调用函数之外,如上面的代码示例所示/

您需要另一个方法,例如:

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

但是因为你使用的是c++,而不是C,所以你不应该返回char*。对于面向对象的设计,使用字符串类为您管理内存,如std::string。(这里有一个要记住的试金石:如果内存在析构函数之外被释放,那么您可能正在做一些不明智的事情。)

下面是一个技巧:

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

当你返回指针时,无论你返回指针的对象是谁,都应该对该资源承担责任(即在使用它时删除它)。

或者,您可以使用智能指针在没有指向它的时候自动删除内存。

创建并返回stl容器或类(例如std::vector, std::string)也是一个可行的选择。

不要返回原始char*。将其封装在一个类中。

假设char数组确实不是以NULL结束的字符串,那么无论如何都需要在返回时包含它的大小。(连续调用glShaderiv来获得长度有点混乱,特别是如果它有性能影响。通过分配更容易存储大小。)

有人建议使用std::string或std::vector作为返回值。虽然每一种方法都在不同程度上起作用,但它们并没有告诉你在每种情况下它是什么。它是要打印的字符串还是有符号的8位整数数组?

向量可能更接近你需要的,但是当你从现在开始看一年后的代码时,你将不知道一个方法的输出向量是否包含着色器信息,而另一个方法也返回一个向量。由于存储空间在技术上是隐藏的,因此vector也可能意味着不希望通过向设备驱动程序方法传递指针来填充缓冲区。

因此,将返回放在一个分配缓冲区并存储分配大小的类中,可以让返回实例超出作用域,并在调用者使用它时删除缓冲区。

现在主体提到托管指针了吗?

如果你不需要向量的特征,那么::array_ptr<char>也可能会有所帮助,而不是像tp1的答案那样自己滚动。取决于编译器的版本,在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;
}