Main Content

MISRA C++:2023 Rule 6.8.1

An object shall not be accessed outside of its lifetime

Since R2024b

Description

Rule Definition

An object shall not be accessed outside of its lifetime.

Rationale

The lifetime of an object starts after it is initialized and ends at the end of its scope, even if the memory occupied by the object is not released. Accessing an object before its lifetime begins and after its lifetime ends results in undefined behavior.

Specific and trivial instances of lifetime violations are covered by MISRA C++:2023 Rule 6.8.2 and MISRA C++:2023 Rule 6.8.3. Other lifetime violations are covered by this rule.

Polyspace Implementation

Polyspace® reports a violation if you access:

  • A block of memory after freeing the block using the free function or the delete operator

  • An object after its destructor is invoked

  • A nonactive union member

  • An unnamed temporary object by reference after the unnamed temporary object goes out of scope

Polyspace does not report taking the address of a nonactive union member as a violation of this rule.

Troubleshooting

If you expect a rule violation but Polyspace does not report it, see Diagnose Why Coding Standard Violations Do Not Appear as Expected.

Examples

expand all

In this example, the delete operator releases the block of memory that myArray refers to. Dereferencing myArray after the delete operation results in a violation.

#include <iostream>
void func()
{
    int* myArray = new int { 5 };
    //...
    delete myArray;
    std::cout << *myArray; //Noncompliant
}

In this example, the object examplePtr is accessed after its destructor is explicitly invoked. Accessing the object after it is destroyed results in undefined behavior and Polyspace reports a violation.

#include <iostream>
#include <string>

class Example {
public:
	Example() { /*...*/ }
	~Example() { /*...*/ }
	void showMessage() { /*...*/ }
};

void foo() {
	unsigned char buffer[sizeof(Example)];
	Example *examplePtr = new(buffer) Example();  // Placement new

	examplePtr->showMessage();
	examplePtr->~Example();
	examplePtr->showMessage(); // Noncompliant
}

In the function foo(), the myUnion object uaw has two members, member1 and member2. Accessing the nonactive member of the union object results in a violation of this rule.

typedef int int32_t;
class myClassA {
	int32_t val = 5;
public:
	myClassA() = default;
	myClassA(myClassA &in) = default;
	int getVal() {
		return val;
	}
};

class myClassB {
	int32_t value = 50;
public:
	myClassB() = default;
	myClassB(myClassB &in) = default;
	int getVal() {
		return value;
	}
};

union myUnion {
	myUnion() {};
	myClassA member1;
	myClassB member2;
};

void foo() {
	myUnion uaw;
	myClassA mca;
	myClassB mcb;

	uaw.member1 = mca;
	uaw.member1.getVal();
	uaw.member2.getVal(); // Noncompliant
}

In this example, the myClass object obj is assigned to an unnamed temporary object. The assignment operator in (myClass{} = a) returns a reference to the temporary object, which then binds to the lvalue reference objref. The temporary object referenced by objref goes out of scope immediately following the statement auto &objref = (myClass{} = a). Accessing the out-of-scope object in subsequent code results in undefined behavior and Polyspace reports a violation.

class myClass {
	int val = 42;
public:
	myClass() = default;
	int getVal() {
		return val;
	}
};

void foo() {
	myClass obj;
	//...
	auto &objref = (myClass{} = a);
	objref.getVal(); // Noncompliant
}

Check Information

Group: Basic concepts
Category: Required

Version History

Introduced in R2024b