2015-10-04 148 views
0

有人可以在这里解释崩溃吗?unique_ptr当调用reset时数组崩溃

#include <iostream> 
#include <memory> 

int main() { 
    int *num1 = new int(5), *num2 = new int(18); 
    std::unique_ptr<int> numptr = std::unique_ptr<int>(num1); 
    std::cout << *numptr.get() << '\n'; // 5 
    numptr.reset(num2); 
    std::cout << *numptr.get() << '\n'; // 18 

    int a[5] = {0,2,4,6,8}, b[5] = {0,3,6,9,12}; 
    std::unique_ptr<int[]> u = std::unique_ptr<int[]>(a); 
    std::cout << u[3] << '\n'; // 6 
    u.reset(b); 
    std::cout << u[3] << '\n'; // Crash. Why??? Should output 9, right? 
} 

没有崩溃调用具有std::unique_ptr<int>复位时,为什么与std::unique_ptr<int[]>崩溃。如我所见,u取得b的所有权,然后删除a。所以u[3]应该是b[3] = 9应该工作正常,因为b不会被删除。这里发生了什么?

+1

'unique_ptr'只能管理动态分配的对象。 “a”和“b”都不是其中之一。 – juanchopanza

+0

那么上面的“u”是做什么的? – prestokeys

+1

'std :: unique_ptr'假定它保存的哑指针在'new'或'new []'的堆上被分配。在其析构函数或reset()中,它试图“删除”或“删除[]”指针。您反而将它提供给堆栈上自动对象的地址。 –

回答

2

你将unique_ptr包装在一个数组中,该数组具有自动存储持续时间,并且它的内存将由运行时释放。在程序结束时,unique_ptr尝试释放相同的内存。基本上线u.reset(b);相当于delete[] a; // then set u to point to b

如果你尝试一个简单的程序像

int main() 
{ 
    int arr[10]; 
    delete[] arr; // runtime error here 
} 

你会得到完全相同的错误。你不应该使用智能指针和非动态对象。

相关问题