Обычный указатель против автоматического указателя (std::auto_ptr)
Фрагмент кода (обычный указатель)
int *pi = new int;
int i = 90;
pi = &i;
int k = *pi + 10;
cout<<k<<endl;
delete pi;
[Output: 100]
Фрагмент кода (автоматический указатель)
Случай 1:
std::auto_ptr<int> pi(new int);
int i = 90;
pi = &i;
int k = *pi + 10; //Throws unhandled exception error at this point while debugging.
cout<<k<<endl;
//delete pi; (It deletes by itself when goes out of scope. So explicit 'delete' call not required)
Случай 2:
std::auto_ptr<int> pi(new int);
int i = 90;
*pi = 90;
int k = *pi + 10;
cout<<k<<endl;
[Output: 100]
Может кто-нибудь сказать, почему это не сработало для случая 1?
2 ответа
Вы пытались связать auto_pt
Перемещаемая в стек переменная.
std::auto_ptr<int> pi(new int);
int i = 90;
pi = &i;
никогда не пытайся делать это - только связывай auto_ptr
переменным, выделенным с new
, В противном случае auto_ptr будет пытаться delete
переменная, выделенная стеком, и это неопределенное поведение.
Случай 1 не компилируется, потому что вы просто не можете назначить простой указатель на auto_ptr
, Если вы хотите изменить указатель, auto_ptr
присмотритесь, вы можете использовать метод сброса:
pi.reset(&i);
Сейчас pi
удалит указатель, который хранился ранее.
Тем не менее, здесь вы будете хранить адрес переменной, размещенной в стеке, которую нельзя удалять. Цель std::auto_ptr
это управлять динамически распределенной переменной.
То, что вы наблюдаете в VC++ 2005, похоже, является ошибкой в реализации функции (возможность назначать указатели на std::auto_ptr
) который явно не указан в стандарте (должен ли он компилироваться или не должен).
В следующем стандарте std::auto_ptr
в любом случае будет устаревшим, так что вы можете поэкспериментировать с более разумными умными указателями (boost::scoped_ptr
, boost::shared_ptr
).