Main Content

AUTOSAR C++14 Rule A20-8-3

A std::shared_ptr shall be used to represent shared ownership

Since R2020b

Description

Rule Definition

A std::shared_ptr shall be used to represent shared 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::shared_ptr object is a smart pointer that solves both problems.

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

  • The pointer has shared ownership of the pointed object. When you pass the pointer to a function, the function assumes ownership of the memory through the pointer and implicitly deallocates the memory on completion as long as no other pointer is pointing to the object.

Although a std::shared_ptr object has some overhead over a raw pointer, the use of this object avoids possible memory leaks later.

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-2.

  • 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::shared_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_shared<Resource>();
    bool valueFound, allSmallerValuesFound;
    
    //Initialize resources
    
    valueFound = doesValueExist(aResourcePtr, getAVal());
    allSmallerValuesFound = doAllSmallerValuesExist(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::shared_ptr pointer to the object as parameter.

Check Information

Group: General utilities library
Category: Required, Automated

Version History

Introduced in R2020b