Main Content

Pointer or reference to destroyed temporary object

Destruction of temporary object results in dangling pointer or reference

Since R2023b

Description

This defect occurs when you create a pointer or reference to a temporary object that goes out of scope at the end of the expression where the pointer or reference is initialized. For example, in this code snippet, the function getStringVector() returns an std::vector initialized with two strings, "John" and "Smith". The function printString() then initializes a pointer ptr with the address of the temporary string that getStringVector()[0] returns. However, the returned string is deleted at the end of the line std::string const *ptr = &getStringVector()[0]; and ptr points to an object that has gone out of scope.

#include <iostream>
#include <vector>
#include <string>

std::vector<std::string> getStringVector()
{
   return std::vector<std::string>{"John", "Smith"};
}

void printString()
{
   std::string const *ptr = &getStringVector()[0];
   std::cout << "Value: " << *ptr;
}

Risk

Accessing a pointer or reference that holds the address of an object that has gone out of scope or that has been deleted is undefined behavior, and might results in unexpected results, data corruption, or a program crash.

Fix

Copy the temporary object to a variable and point to or reference that variable instead.

Examples

expand all

#include <iostream>
#include <vector>

std::vector<std::string> generateTestName()
{
   return std::vector<std::string>{"John", "Smith"};
}

void test_func()
{
   const std::string &lastName = generateTestName()[1];
}

In this example, the function generateTestName returns an std::vector that is initialized with a pair of strings ("John" and "Smith"). In the function test_func(), the call to generateTestName()[1] returns an std::string object ("Smith").

Polyspace reports the attempt to bind a constant reference lastName to the temporary object returned by generateTestName()[1] as a defect. The object that generateTestName()[1] returns goes out of scope at the end of the expression that declares lastName (const std::string &lastName = generateTestName()[1];). After the temporary object is destroyed, the reference lastName might point to an invalid memory location which can result in undefined behavior.

Correction — Copy Temporary Object and Bind Reference to Copy

One possible correction is to copy the string returned by generateTestName()[1] to a variable myCopy, and then bind the reference lastName to myCopy.

#include <iostream>
#include <vector>

std::vector<std::string> generateTestName()
{
   return std::vector<std::string>{"John", "Smith"};
}

void test_func()
{
   const std::string myCopy = generateTestName()[1];
   const std::string &lastName = myCopy;
}

Result Information

Group: Programming
Language: C++
Default: Off
Command-Line Syntax: POINTER_TO_TEMPORARY_OBJECT
Impact: High

Version History

Introduced in R2023b

expand all