原始指针可以指向在堆栈上或堆上分配的对象。
堆分配示例:
// heap allocation
int* rawPtr = new int(100);
std::cout << *rawPtr << std::endl; // 100
堆栈分配示例:
int i = 100;
int* rawPtr = &i;
std::cout << *rawPtr << std::endl; // 100
使用auto_ptr进行堆分配示例:
int* rawPtr = new int(100);
std::unique_ptr<int> uPtr(rawPtr);
std::cout << *uPtr << std::endl; // 100
使用auto_ptr示例堆栈分配:
int i = 100;
int* rawPtr = &i;
std::unique_ptr<int> uPtr(rawPtr); // runtime error
智能指针&#39;是否用于指向堆上动态创建的对象?对于C ++ 11,我们是否应该继续使用原始指针来指向堆栈分配的对象?谢谢。
答案 0 :(得分:5)
智能指针通常用于指向使用new
分配的对象,并使用delete
删除。它们不必以这种方式使用,但如果我们想要猜测语言结构的预期用途,那似乎就是意图。
您的代码在上一个示例中崩溃的原因是因为&#34;已删除了delete
&#34;部分。当它超出范围时,unique_ptr将尝试delete
它有指针的对象。由于它是在堆栈上分配的,因此失败了。就像你写过delete rawPtr;
由于通常使用带有堆对象的智能指针,因此有一个函数可以在堆上进行分配并一次性转换为智能指针。 std::unique_ptr<int> uPtr = make_unique<int>(100);
将执行第三个示例的前两行的操作。共享指针也有匹配的make_shared
。
可以使用带有堆栈对象的智能指针。你要做的是指定智能指针使用的删除器,提供一个不调用delete
的删除器。由于它是一个堆栈变量并且不需要删除它,所以删除器无能为力。这让人问,那么智能指针的重点是什么,如果它只是调用一个什么都不做的函数?这就是为什么你不常常看到与堆栈对象一起使用的智能指针。但这是一个显示一些有用性的例子。
{
char buf[32];
auto erase_buf = [](char *p) { memset(p, 0, sizeof(buf)); };
std::unique_ptr<char, decltype(erase_buf)> passwd(buf, erase_buf);
get_password(passwd.get());
check_password(passwd.get());
}
// The deleter will get called since passwd has gone out of scope.
// This will erase the memory in buf so that the password doesn't live
// on the stack any longer than it needs to. This also works for
// exceptions! Placing memset() at the end wouldn't catch that.
答案 1 :(得分:3)
运行时错误是由于delete
在从未使用new
分配的内存位置上调用的事实。
如果已经使用dynamic storage duration创建了一个对象(通常在&#39;堆上实现创建),那么“智能指针”将被创建。如运行时错误所示,它将无法正常运行。
智能指针&#39;旨在用于动态指向 在堆上创建了对象?对于C ++ 11,我们应该继续 使用原始指针指向堆栈分配的对象?
至于应该做什么,这有助于考虑存储持续时间,特别是对象的创建方式。
所以对于最后一个例子,以下会更好(指针拥有int):
auto uPtr = std::make_unique<int>(100);
uPtr
将具有自动存储持续时间,并在超出范围时调用析构函数。 int
将具有动态存储持续时间(堆),并由智能指针进行delete
。
通常可以避免使用new
和delete
并避免使用原始指针。使用make_unique
和make_shared
,new
并非必需。
答案 2 :(得分:3)
智能指针&#39;是否用于指向堆上动态创建的对象?
它们用于堆分配的对象以防止泄漏。
C ++的指导原则是使用引用的普通指针指向单个对象(但不拥有它)。对象的所有者通过值,容器或智能指针保存它。
答案 3 :(得分:1)
智能指针&#39;是否用于指向堆上动态创建的对象?
是的,但那只是默认值。请注意std::unique_ptr
在该页面上有一个constructor(no(3)/(4)),它带有你以某种方式获得的指针,以及一个&#34;删除器&#34; 你提供的。在这种情况下,唯一指针不会对堆做任何事情(除非你的删除器这样做)。
对于C ++ 11,我们是否应该继续使用原始指针来指向堆栈分配的对象?谢谢。
你应该在没有&#34;拥有&#34;的代码中使用原始指针。指针 - 不需要关心分配或释放;无论你是指向堆还是堆栈或其他地方,都是如此。
另一个使用它的地方是当你为受保护/私人成员实施一些具有复杂所有权模式的类时。
PS:请忘记std::auto_ptr
...假装它从未存在过: - )