在函数和内存泄漏中为返回值分配内存

时间:2013-08-07 10:29:28

标签: c++

我有一个功能:

char const* GetData() const 
{
      char* result = new char[32];
      sprintf(result, "My super string");

      return result;
}

Adn然后在屏幕上显示如下字符串:

std::cout << GetData() << std::endl;

或者有一个班级:

class MyClass()
{
    char m_data[32]
public:
     MyClass(const char* data) { strcpy(m_data, data) } ;
}

创建一个对象的实例:

MyClass obj = new MyClass(GetData());

我分配char* result = new char[32];并且永远不会删除它。我该如何处理内存泄漏?我该如何释放记忆?

3 个答案:

答案 0 :(得分:9)

C ++ best feature主要来自其确定性对象破坏(这是最初取自Bjarne的一点)。

它允许RAII成语。所以一定要阅读它,然后应该清楚你应该总是使用对象来管理资源。 基本上,当您编写程序时,您确切地知道何时将调用每个对象的析构函数。因此,您可以利用这些知识将资源管理委派给析构函数将释放资源的对象(并确保在您想要释放资源时实际销毁对象^^)

正如注释中所指出的,如果你需要一个字符串,STL为你提供了一个非常好的对象来管理底层的动态char数组生命周期:

 std::string

如何重写第一个方法

利用 std :: string 设施:

std::string GetData() const 
{
     return std::string("My super string");
}

但是你可能不需要这里的函数,只需在代码中的任何地方直接创建 std :: string 对象。

答案 1 :(得分:1)

首先,在使用C ++中的字符串时总是使用std::string。它安全,快速,高效。

其次,在处理动态内存时不要使用裸指针(例如char* naked_ptr = new char[32])。而是始终将指针包装在智能指针中,例如std::unique_ptrshared_ptr。如果你使用智能指针,你不必担心资源的释放,因为它会自动为你完成。

现在回答你的问题:
您丢失指向它的指针时无法删除内存。

您的函数GetData返回指向它动态分配的内存的指针。然后将指针传递给MyClass的构造函数,该构造函数使用它来复制指向的数据。接下来,指针被销毁,因为GetData()会产生一个临时对象,该对象仅在对构造函数的调用期间存在。

要解除分配指针所需的内存,以便{@ 1}}它。

例如:

delete[]

或者您可以使用这样的智能指针:

const char* p = GetData()
MyClass* obj = new MyClass(p); // obj must be a pointer or it won't compile.
/* do stuff */
delete obj; // You should also delete obj.
delete[] p;

<强>然而
让函数返回动态分配的内存是一个不好的做法,因为它使得调用者负责清理它。

答案 2 :(得分:0)

  

我分配了char * result = new char [32];永远不要删除它。怎么样   我应该处理内存泄漏吗?我该如何释放记忆?

delete [] result;

和你的班级一起,

MyClass *obj = new MyClass(...)    
delete obj;

因为你的函数分配内存并且永远不会破坏数组,所以调用者有责任释放内存。因此,如果您将结果传递给 MyClass 构造函数,则应该实现delete [] result;在 MyClass 析构函数中。