帮助修复内存泄漏

时间:2011-04-25 01:54:48

标签: c++ memory-leaks memory-management

我有一个成员函数,我需要在运行时获取一些char数组

我的恐惧
如果我试试

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

7 个答案:

答案 0 :(得分:3)

您应该返回std::vector<char>。这样,当调用者完成使用向量时,其内容将自动释放。

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

答案 1 :(得分:3)

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

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

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

所示

答案 2 :(得分:1)

您需要其他方法,例如:

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

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

答案 3 :(得分:0)

当你返回指针时,无论你返回什么指针都应该对该资源负责(即完成后删除它)。

或者,您可以使用智能指针在没有任何内容时自动删除内存。

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

答案 4 :(得分:0)

这是一个如何做到的技巧:

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

答案 5 :(得分:0)

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

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

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

向量可能更接近您的需要,但是当您从现在起查看代码时,您将不知道一个方法的输出向量是否包含着色器信息与另一个方法相比还是返回向量。由于存储在技术上是隐藏的,因此向量的含义可能会使得通过将指针传递给设备驱动程序方法来填充缓冲区这样做是不可取的。

因此,将返回值放在一个分配缓冲区并存储分配大小的类中,可以让返回实例超出范围,并在调用者完成后删除缓冲区。

答案 6 :(得分:0)

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

如果您不需要向量的功能,那么::array_ptr<char>也可能有助于而不是像tp1's answer那样滚动自己的功能。取决于编译器的版本,可在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;
}