Обычный указатель против автоматического указателя (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).

Другие вопросы по тегам