Use of new or make_unique instead of more efficient make_shared

Используя new или make_unique инициализировать или сбросить shared_ptr результаты в дополнительном выделении памяти

Описание

Этот дефект происходит, когда вы используете:

  • new или make_unique инициализировать shared_ptr экземпляр. Например:

    std::shared_ptr<T> p1(new T());
    std::shared_ptr<T> p2(make_unique<T>());

  • new сбрасывать shared_ptr экземпляр. Например:

    std::shared_ptr<T> p1;
    //...
    p1.reset(new T);

Вы используете shared_ptr экземпляры, когда это необходимо, несколько интеллектуальных указателей, чтобы владеть и управлять тем же объектом. Экземпляры также совместно используют блок управления, который содержит количество количества экземпляров, которые владеют управляемым объектом.

Polyspace® не отмечает использование new инициализировать shared_ptr экземпляр в частных или защищенных конструкторах. Например, никакой дефект не повышен на использовании new в этом фрагменте кода:

class PrivateCTor
{
public:
    static std::shared_ptr<PrivateCTor> makeOne()
    {
        return std::shared_ptr<PrivateCTor>(new PrivateCTor);
    }
private:
    PrivateCTor();
};

Риск

Когда вы используете new или make_unique инициализировать shared_ptr экземпляр, операция дополнительных ассигнований создает устройство хранения данных для блока управления. Адрес дополнительных ассигнований может быть в различной странице памяти или возле кэша данных по сравнению с адресом управляемого объекта.

Фиксация

Используйте std::make_shared инициализировать shared_ptr экземпляр. Функция выполняет одну операцию выделения с достаточной памятью, чтобы хранить управляемый объект и блок управления.

Повышения производительности могут варьироваться на основе компилятора, реализации библиотеки и среды, которую вы используете.

Примеры

развернуть все

#include <memory>
#include <string>

struct Profile {
    virtual ~Profile() = default;
};

struct Player : public Profile {
    std::string name;
    std::int8_t rank;

    Player();
    Player(const std::string& name_, const std::int8_t& rank_) :
        name{ name_ }, rank{ rank_ } {}
};

void func()
{

    std::shared_ptr<Player> player1(new Player("Serena Williams", 1));
    std::shared_ptr<Player> top_rank(player1);

}

В этом примере Polyspace отмечает использование new инициализировать player1. Программа выполняет операцию дополнительных ассигнований для блока управления, который содержит счетчик всех экземпляров shared_ptr это владеет управляемым Player объект.

Коррекция — использует std::make_shared инициализировать shared_ptr

Одна возможная коррекция должна использовать std::make_shared инициализировать player1.

#include <memory>
#include <string>

struct Profile {
    virtual ~Profile() = default;
};

struct Player : public Profile {
    std::string name;
    std::int8_t rank;

    Player();
    Player(const std::string& name_, const std::int8_t& rank_) :
        name{ name_ }, rank{ rank_ } {}
};

void func()
{

    auto player1 = std::make_shared<Player>("Serena Williams", 1);
    std::shared_ptr<Player> top_rank(player1);

} 

Информация о результате

Группа: Производительность
Язык: C++
Значение по умолчанию: Off
Синтаксис командной строки: MISSING_MAKE_SHARED
Удар: низко
Введенный в R2021a