0

我有一个功能:

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

      return result;
}

然后在屏幕上显示这个字符串,如下所示:

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];并且从不删除它。我应该如何处理内存泄漏?我应该如何释放内存?

4

3 回答 3

9

C++最好的特性主要来自于它的确定性对象破坏(这是最初取自 Bjarne 的一点)。

它允许使用RAII习语。因此,请务必阅读它,然后应该清楚您应该始终使用对象来管理资源。本质上,当您编写程序时,您确切知道何时调用每个对象的析构函数。因此,您可以利用这些知识将资源管理委托给一个对象,该对象的析构函数将释放您的资源(并确保在您想要释放资源时该对象实际上已被破坏^^)

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

 std::string

如何重写你的第一个方法

利用std::string设施:

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

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

于 2013-08-07T10:34:39.343 回答
1

首先,std::string在 C++ 中处理字符串时始终使用。它安全、快速、高效。

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

现在回答您的问题:
您无法删除内存,因为您丢失了指向它的指针。

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

要释放内存,您需要跟踪该指针,以便您可以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;

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

std::unique_ptr<char[]> p(GetData());
std::unique_ptr<MyClass> obj(new MyClass(p.get()));
/* do stuff */

但是
,让函数返回动态分配的内存是一种不好的做法,因为它使调用者负责对其进行清理。

于 2013-08-07T11:40:35.437 回答
0

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

delete [] result;

和你的班级,

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

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

于 2013-08-07T11:04:53.807 回答