2011-04-25 47 views
2

我有,我需要在运行时获取一些字符数组帮助的固定内存泄露

我担心
是,如果我尝试

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

回答

2

您应该返回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

为什么不只是返回一个std :: string? – 2011-04-25 02:01:30

+0

@Andrew:你可以,从C++ 0x开始。在C++ 03和更早的版本中,没有具体的保证'std :: string'必须是连续的(尽管实际上它们必须是)。 – 2011-04-25 02:02:28

0

当您返回该指针时,无论您返回的指针应该对该资源承担责任(即在完成该操作时将其删除)。

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

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

+0

这个答案有什么问题? – helloworld922 2011-04-25 02:07:53

+0

没什么,我想。我相信在这个主题中有一个系列downvoter,谁已经在这里下了很多答案(包括我的和tommieb的)。 – 2011-04-25 02:39:02

+0

哦,好的。我并不担心投票结果,因为我错过了一些显而易见的事情(这在一天结束时很重要) – helloworld922 2011-04-25 05:29:35

1

你得找别的方法,比如:

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

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

+1

'delete s'是错误的。它应该是'delete [] s'。 – 2011-04-25 02:01:22

+0

@克里斯很好抓...固定。 – 2011-04-25 02:02:23

0

这里有一个窍门如何做到这一点:

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

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

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

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

0

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

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

有些人建议使用std :: string或std :: vector作为回报。尽管每种方法都可以在不同程度上发挥作用,但它们并不会告诉你每种情况下的情况。它是一个你打印的字符串,还是一个有8位整数的数组?

一个向量可能更接近你所需要的,但是当你从现在开始每年看代码时,你将不知道一个方法的输出向量是否包含着色器信息,一个向量。也可能存在向量的含义,使得像通过将指针传递给设备驱动程序方法来填充缓冲区这样的事情是不可取的,因为存储在技术上是隐藏的。

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

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