Main Content

AUTOSAR C++14 Rule A20-8-2

A std::unique_ptr shall be used to represent exclusive ownership

Since R2020b

Description

Rule Definition

A std::unique_ptr shall be used to represent exclusive ownership.

Rationale

Raw pointers to heap memory suffer from two related problems:

  • When a raw pointer goes out of scope, the pointed memory might not be deallocated and result in a memory leak. You have to remember to explicitly deallocate the memory (delete the pointer) before the pointer goes out of scope.

  • If you pass a raw pointer to a function, it is unclear if the function takes exclusive ownership of the pointed resource and can deallocate the memory or must leave the deallocation to the caller. If the function deallocates the memory, there is a risk that another pointer pointing to the same memory location is now left dangling.

A std::unique_ptr object is a smart pointer that solves both problems and does not require significant additional overheads over raw pointers:

  • You do not have to explicitly deallocate the pointed memory. The memory is deallocated before the pointer goes out of scope.

  • The pointer has exclusive ownership of the pointed object. When you pass the pointer to a function by a move operation, the function assumes ownership of the memory through the pointer and implicitly deallocates the memory on completion (unless you pass the ownership to another function).

Polyspace Implementation

The checker flags functions other than main that have raw pointers as parameters or return values.

The checker raises a violation of both this rule and AUTOSAR C++14 Rule A20-8-3.

  • If you want the function to take exclusive ownership of the pointed object, convert the raw pointer to std::unique_ptr type.

  • If you want the function to take shared ownership of the pointed object, convert the raw pointer to std::shared_ptr type.

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

#include <memory>
#include <cstdint>
#include <thread>
constexpr std::uint32_t SIZE=100;

class Resource {
  public:
    bool lookup(std::int32_t);
  private:
    std::int32_t arr[SIZE];
};

bool doesValueExist(Resource *aResource, std::int32_t val) { //Noncompliant
    return aResource->lookup(val);
}

bool doAllSmallerValuesExist(std::unique_ptr<Resource> aResource, std::int32_t val) { 
//Compliant
    bool valueExists = true;
    for(std::int32_t i = 0; i <= val; i++) {
        valueExists = aResource->lookup(i);
        if(!valueExists)
            break;
    }
    return valueExists;
}

std::int32_t getAVal();

void main(void) {
    Resource *aResourcePtr = new Resource;
    auto anotherResourcePtr = std::make_unique<Resource>();
    bool valueFound, allSmallerValuesFound;
    
    //Initialize resources
    
    valueFound = doesValueExist(aResourcePtr, getAVal());
    allSmallerValuesFound = doAllSmallerValuesExist(std::move(anotherResourcePtr), getAVal());
}

In this example, the function doesValueExist takes a raw pointer to a Resource object as parameter and violates the rule.

The function doAllSmallerValuesExist performs similar operations on a Resource object but takes an std::unique_ptr pointer to the object as parameter.

Check Information

Group: General utilities library
Category: Required, Automated

Version History

Introduced in R2020b