简体   繁体   中英

In C++ does returning a string created from a local char array cause a memory leak or undefined behavior?

I am wondering if this would cause a memory leak or an undefined outcome in C++?

string foo()
{
    char tempArray[30];
    strcpy(tempArray, "This is a test");
    return string(tempArray);
}

I know this is a bad thing in C but I haven't found a definite answer for C++.

So everyone is saying no, but I am still confused as to when the memory is deallocated?

Lets say I have this method that calls the above method

void bar()
{
    string testString = foo();
}

At what point in the above code does the string object returned from foo() call its destructor? Is it immediately after getting copied into the object testString?

No, there is no memory leak, and you don't need to do all that, here is equivalent to your code

string foo()
{
 return "This is a test";
}

In this code:

char tempArray[30];

tempArray is a variable with automatic storage duration. When tempArray "falls out of scope" it is automatically destroyed. You copy the contents of this array (somewhat clumsily) in to a std::string and then return that string by value. Then tempArray is destroyed. It;s important to note here that tempArray is the array . It is not a pointer to the first element of the array (as is commonly mis-perceived), but the array itself. Since tempArray is destroyed, the array is destroyed.

There would be a leak if you used a variable with dynamic storage duration, such as with:

  char* tempArray = new char[30];
  strcpy(tempArray, "This is a test");
  return string(tempArray);

Note the new[] with no matching delete[] . Here, tempArray is still a variable with automatic storage duration, but this time it is a pointer, and the thing that it points to has dynamic storage duration. In other words, tempArray gets destroyed when it falls out of scope, but it's just a pointer. The thing that it points to -- the char array itself, is not destroyed because you don't delete[] it.

不是特别有效,但没有,没有泄漏。

No, it wouldn't cause any leaks as you never allocate memory on the heap. If you used malloc , calloc or new .. and you never free / delete it. Then yes, memory leak!

The array is statically allocated, so it is created on the stack. strcpy doesn't return a dynamically allocated object, it fills the existing array, it knows how to do this because of the pointer you passed in - again, not allocated on the heap. A copy of the string object is made when you return the string.

What happens in your example is that the constructor with the signature

string ( const char * s );

is called. The constructor allocates new memory for a copy of the string and copies it to that new memory. The string object is then responsible for freeing its own memory when its destructor is called.

When you make a copy of a string, the copy constructor also allocates memory and makes a copy.

You should also take a look at the RAII pattern. This is how string 's memory management works.

You can always return local automatic variable from function by value. For any type this should be safe (unless copy constructor is not safe):

T foo()
{
   return T(...);
}

or:

T foo()
{
   T t
   return t;
}

Your example matches my first case.

What is not safe is returning pointer/reference to local automatic variable:

T& foo()
{
   T t
   return t;
}

T* foo()
{
   T t
   return &t;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM