Верно ли мое предположение, что в следующем примере память, на которую ссылается b, будет освобождена, как только экземпляр A выйдет из области видимости в конце func(), правильно?

class A{
public:
   A() {
        b = std::shared_ptr<char>(new char[100] { 0 } );
   }
   char* b;
}

void func {
   A a;
}
1
chutiya 30 Окт 2015 в 06:27

2 ответа

Лучший ответ

Нет, не правильно. b имеет тип char *, и вы назначаете ему shared_ptr<char>. Вы должны получить ошибку компиляции.

Кроме того, конструктором является private, еще одна ошибка компиляции.

И как получить доступ к b в func()? Это личное в A.

Очевидно, ваше упражнение не завершено ... поэтому я просто исхожу из того, что вы предоставили.

Также я предлагаю использовать unique_ptr, если вы можете сказать, что это уникальное право собственности (что, на мой взгляд, так).

Это компилирует:

#include <memory>
#include <iostream>

class A {
public:

    A() {
        std::cout << "A created with unique pointer" << std::endl;
        b = std::unique_ptr<char>(new char[100] {
            0
        });
    }

    ~A() {
        std::cout << "A destroyed" << std::endl;
    }

private:
    std::unique_ptr<char> b;
};

void func() {
    A a;
}

int main() {
    std::cout << "Call func()" << std::endl;
    func();
    std::cout << "func() called" << std::endl;
    return 0;
}

И в конце func() A уничтожается, а вместе с ним и unique_ptr.

Однако спросите себя, действительно ли вам нужно использовать указатель? В вашем случае автоматическая переменная вполне подойдет; он делает то же самое (т. е. уничтожается при выходе из func().

3
Ely 30 Окт 2015 в 05:23

Вы назначаете члену char*, поэтому я почти уверен, что shared_ptr будет очищен, как только назначение будет завершено (поскольку оно не было сохранено в другом shared_ptr, которое могло бы поддерживать счетчик ссылок).

Если вы хотите использовать shared_ptr, вы должны использовать их последовательно; член класса необработанного указателя ничего за вас не может управлять. Указатель по-прежнему инициализируется там, где была выделена память, но больше не выделяется; доступ к нему даже на строчку позже в конструкторе будет неопределенным поведением / ошибкой использования после освобождения.

В любом случае небезопасно , потому что по умолчанию shared_ptrиспользует delete, а не delete[]. Есть ли причина, по которой нельзя использовать std::shared_ptr<std::array<char, 100>>?

2
ShadowRanger 30 Окт 2015 в 04:04