Romz
Romz

Reputation: 1457

Allocation of memory for return value in function and memory leaks

I have a function:

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

      return result;
}

Adn then show this string on the screen like this:

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

Or have a class:

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

And create an instance of an object:

MyClass obj = new MyClass(GetData());

I allocate char* result = new char[32]; and never delete this. How should I deal with memory leak ? How should I free the memory ?

Upvotes: 0

Views: 1619

Answers (3)

Ad N
Ad N

Reputation: 8376

C++ best feature mainly comes from its deterministic object destruction (this is a point originally taken from Bjarne).

It allows the RAII idiom. So make sure to read about it, then it should be clear that you should always use objects to manage resources. Essentially, when you write your program, you know exactly when each object's destructor will be called. So you use that knowledge at your advantage to delegate resource management to an object whose destructor will free your resources (and make sure the object is actually destructed when you want to free the resource ^^)

As pointed in comments, if you need a string of characters, the STL gives you a very good object to manage the underlying dynamic char array lifetime :

 std::string

How to rewrite you first method

Taking advantage of the std::string facility :

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

But you probably do not need the function here, just create the std::string object directly wherever you need it in your code.

Upvotes: 9

Felix Glas
Felix Glas

Reputation: 15524

First of all, always use std::string when working with strings in C++. It's safe, fast and efficient.

Secondly, never use a naked pointer when handling dynamic memory (e.g. char* naked_ptr = new char[32]). Instead always wrap your pointers in a smart pointer, e.g. std::unique_ptr or shared_ptr. If you use smart pointers you don't have to worry about deallocating resources as it's done automatically for you.

And now to answering your question:
You can't delete the memory as you have lost the pointer pointing to it.

Your function GetData returns a pointer to the memory it allocates dynamically. Then you pass the pointer to the constructor of MyClass which uses it to copy the data pointed to. Next the pointer is destroyed as GetData() results in a temporary object that only exists during the call to the constructor.

To deallocate the memory you need to keep track of that pointer so you can delete[] it.

For example:

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;

Or you could use smart pointers like this:

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

However
It's a bad practice to let a function return dynamically allocated memory as it makes the caller responsible to clean up after it.

Upvotes: 1

Karadur
Karadur

Reputation: 1246

I allocate char* result = new char[32]; and never delete this. How should I deal with memory leak ? How should I free the memory ?

delete [] result;

and with your class,

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

Because your function allocates memory and never destroys the array, it's a caller's responsibility to free memory. So if you pass result to MyClass constructor, you should probably implement delete [] result; in MyClass destructor.

Upvotes: 0

Related Questions