采访中的共享指针查询 [已关闭]

Shared Pointer query in an interview [closed]

提问人:Tej Ravi 提问时间:11/8/2023 最后编辑:463035818_is_not_an_aiTej Ravi 更新时间:11/8/2023 访问量:221

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章用事实和引文来回答。

11天前关闭。

以下代码中哪个更好

int  *a=new int();
shared_ptr<int> sh(a);

或者这个

shared_ptr<int> sh(new int());

面试官暗示第一个案例有问题,make_shared消除了这个问题。 谁能给我指出正确的答案?

C++ C++14 智能指针

评论

4赞 n. m. could be an AI 11/8/2023
这两种情况都有相同的问题。
3赞 Some programmer dude 11/8/2023
在谈论“更好”或“更差”时,总是需要一些上下文。这两个片段本身并没有真正的意义,没有上下文。此类面试问题应始终通过要求提供更多详细信息来满足。如果没有给出,那么这是一个不好的迹象,在考虑在那里就业的可能性时,您需要牢记这一点。
2赞 Den-Jason 11/8/2023
这回答了你的问题吗?使用 make_shared 时会发生什么
4赞 Alexey S. Larionov 11/8/2023
第一个变体的唯一问题是你仍然有变量。如果共享指针碰巧被销毁,则会成为指向已删除数据的悬空指针。使用 指向的值是无效的aaa
2赞 Den-Jason 11/8/2023
这个问题的问题是该示例与 不相关。这是一个关于使用的问题(我怀疑是)还是关于使用临时的问题(我怀疑不是)make_shared eliminates that problemmake_shared

答:

3赞 463035818_is_not_an_ai 11/8/2023 #1

以下代码中哪个更好

两者都不是。

面试官暗示第一个案例有问题,make_shared消除了这个问题。

要解决的一个主要问题是异常安全性。此处对此进行了解释:make_shared

此外,如果 g 抛出异常,诸如 之类的代码可能会导致内存泄漏,因为可能会在 的构造函数之后和之前调用。这不会发生在 中,因为两个函数调用永远不会交错。f(std::shared_ptr<int>(new int(42)), g())g()new int(42)shared_ptr<int>f(std::make_shared<int>(42), g())

在您的代码示例中,这不是问题。然而,有时解决问题就足以让你永远喜欢它。否则,这两个示例对于使用原始示例同样糟糕,通常应避免使用(参见例如 https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#r11-avoid-calling-new-and-delete-explicitly 和 c++ 代码指南中的其他项目符号)。make_sharednew

谁能给我指出正确的答案?

面试官具体想听到什么,只有他们才能知道。对于单个整数,您可能只需要

int a = 0;

评论

0赞 MSalters 11/8/2023
这个问题被标记为 C++14,所以这确实是正确的,只有使用 C++17 才能保证函数参数计算不会交错。因此,在 C++17 中终于安全了。 被称为第一个或最后一个,在这两种情况下,它都不代表是否投掷。f(std::shared_ptr<int>(new int(42)), g())g()g()
0赞 463035818_is_not_an_ai 11/8/2023
@MSalters afaik 中,还有其他示例在 C++17 之前已经修复。我包括的那个只是我发现的第一个。我不认为它对手头的问题太重要,因为它只能抛出 OP 代码并且不会导致泄漏make_sharednew int
2赞 kaba 11/8/2023 #2

正如@463035818-is-not-an-ai已经回答的那样,面试官的意图只有他们自己知道。也已经说过:两种选择都是等价的。也许他/她想评估你对 或现代 C++ 的了解。make_shared

您可以在此处找到当前文档: https://en.cppreference.com/w/cpp/memory/shared_ptr/make_shared . 在 C++17 之前,在某些情况下,异常安全性确实是一个问题。make_shared

一个有趣的区别是完成的分配数量:

  • 两个分配 ,shared_ptr<int> sh(new int());
  • 一个分配。auto sh = make_shared<int>();

有关所有详细信息,请参阅“注释”。

3赞 Austin Yang 11/8/2023 #3

第一种情况将创建另一个指针实例,这使得其他用户不小心删除了已经删除的指针。

2赞 Kapila Shobit 11/8/2023 #4

“make_shared”是一种更安全、更可靠的动态分配内存并将其与“shared_ptr”相关联的方式。通常建议在使用 shared_ptr 时使用“make_shared”,因为它在某些情况下提供了更好的异常安全性和改进的性能(因为它可以通过组合控制块和指向对象的内存分配来减少内存开销)。