Инициализация boost :: scoped_ptr с другими scoped_ptr вызывает проблему. Этот код правильный - PullRequest
0 голосов
/ 05 ноября 2019

Я новичок в улучшении библиотеки и пытаюсь boost::scoped_ptr, он утверждает, что этот умный указатель не может быть скопирован или перемещен. Но я играл с некоторым кодом и нашел проблему. Мне удалось создать новый экземпляр scoped_ptr и инициализировать его с существующим действительным scoped_ptr. Поэтому, если одна из областей действия scoped_ptr завершена и освобождает память, другой scoped_ptr по-прежнему считает свой действительный указатель и пытается получить доступ. Это дало мне ошибку во время выполнения.

Я работаю над улучшающей библиотекой версии 1.66, с компилятором cygwin g ++ и использую опцию std = c ++ 03 при компиляции.

#include<boost/scoped_ptr.hpp>
#include<iostream>

using namespace std;

int main(){
    boost::scoped_ptr<int> pi(new int(9));
    cout << *pi << endl;
    cout << uintptr_t(pi.get()) << endl;

    boost::scoped_ptr<int> ppi(pi.get()); // initialized with same memory pointed by pi.
    cout << *ppi << endl;                 // so ownership of same memory is with pi.
    cout << uintptr_t(ppi.get()) << endl; // as well as with ppi.

    pi.reset(new int(12)); //its previous memory location pointing to 9 is deallocated.

    cout << *ppi << endl;                  // throws garbage value.. 
    cout << uintptr_t(ppi.get()) << endl;  // shows same memory location it had previous memory shown by pi. 

    cout << *pi << endl;
    cout << uintptr_t(pi.get()) << endl;

    return 0;
}

Итак, ниже приведен снимок кода, выполняемого после точной компиляции ...

-> g++ -std=c++03 -Wall scoped_ptr.cpp 

-> ./a.exe 
9
25769804960
9
25769804960
-2144292696
25769804960
12
25769879920
Aborted (core dumped)

В конце выполнения отображается дамп ядра, он неправильно отображается -2144292696 в предыдущем запуске,

Также я проверил boost::scoped_ptr смог назначить его указателю
int * p = pi.get() оператор компилируется нормально (это сработает?)

Выше операции инициализируется scoped_pt r с другимиscoped_ptr действителен?

1 Ответ

1 голос
/ 05 ноября 2019

Указанная выше операция инициализации scoped_ptr с другими scoped_ptr действительна?

Нет. Повышенная документация читает:

explicit scoped_ptr(T * p = 0); // never throws

Создает scoped_ptr, хранящий копию p, которая должна быть выделена через C ++new выражение или be 0.

Когда вы инициализируете один умный указатель с необработанным указателем, который удерживается другим умным, вы не передаете владение, вы просто делаете копию необработанногоуказательСледовательно, этот указатель будет delete d несколько раз, что является неопределенным поведением.

То, что делает ваш код, по существу таково:

int* p = new int;
delete p;  // when you call pi.reset()
delete p;  // when ppi goes out of scope

.get() возвращает сохраненный необработанный указатель. Он не проверяет его действительность.

Чтобы передать право собственности, вам нужно самостоятельно переместить-назначить умный указатель. Простой пример с std::unique_ptr и C ++ 11:

auto p = std::unique_ptr<int>(new int);
// auto p1 = std::unique_ptr<int>(p.get()); // same error
auto p2 = std::move(p); // fine, transfers ownership from p to p2; 
                        // p will not delete the raw pointer it previously held

boost::scoped_ptr не поддерживает передачу права собственности.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...