C++ 通过新的内存分配

C++ 通过新的内存分配,c++,new-operator,C++,New Operator,我的第一个问题是,函数结束时,new在函数中分配的内存是否会自动删除或分配 int* foo() { int *a = new int; //memory allocated for an int *a = 3; return (a); }//function ends -- is memory for integer still allocated. 如果在函数结束后自动取消分配内存,那么我的下一个代码不应该给出一些与访问不属于我的内存相关的错误吗 int main

我的第一个问题是,函数结束时,new在函数中分配的内存是否会自动删除或分配

int* foo()
{
    int *a = new int;  //memory allocated for an int
    *a = 3;
    return (a);
}//function ends -- is memory for integer still allocated.
如果在函数结束后自动取消分配内存,那么我的下一个代码不应该给出一些与访问不属于我的内存相关的错误吗

int main()
{
    int *x = foo();
    cout<<*x;
}

否,内存未释放

您应该使用delete a手动解除分配它

在Java或C等语言中,有一个所谓的垃圾收集器,当它发现不再需要某些数据时,会处理内存释放。垃圾回收可以与C++一起使用,但它不是标准的,实际上很少使用。
但是,您可以使用其他机制来自动释放内存。共享指针就是其中之一。它们引入了额外的开销。在常规C++代码中,程序员通常负责手动管理内存分配和释放。对于初学者来说,在切换到更高级的机械装置之前先学习基础知识是很重要的。

不,当然不是。每一个新的都必须用删除来平衡。而且,为了避免将来出现任何疑问,任何新[]都必须与删除[]保持平衡


<> C++中有一些构造,一旦容器对象超出范围,就允许有效地释放内存。查看std::shared_ptr和std::unique_ptr。

否,您有责任促成交易:

int *i = new int;
delete i;
然而,上述代码迟早会演变成几乎不可能使异常安全的东西。最好不要使用指针,或者如果您确实必须使用,请使用智能指针,它将在适当的时候为您释放内存:

std::shared_ptr<int> i (new int);
*i = 0xbeef;
return i;
存在其他具有不同所有权语义的智能指针

对于大多数现实世界的应用程序,智能指针引入的任何强加或假定的开销通常很容易与更昂贵的开销相比较,我的意思是节省资金的东西,如可维护性、可扩展性、异常安全性,而这些都混合在其他两个方面

永远不要忘记,根据具体情况,存在指针的替代方案:

标准容器:如果您需要数组之类的东西 智能指针:如果你真的需要一个指针 引用:您不能忘记取消分配 普通对象:根本没有指针。依赖于复制和移动,这通常会带来高度的可维护性、可扩展性、异常安全性和性能。在C++中,这应该是默认的选择。
从一个函数中动态分配并依赖其他函数来取消分配是一种不好的做法。理想情况下,调用者应该分配空间,将其传递给调用函数,调用者将在不使用时解除分配

void foo(int * a)
{
    // a is pre-allocated by caller
    *a = 3;
}//function ends -- caller takes care of allocation and deallocation

int main()
{
    int *x = new int; // memory allocated for an int by caller
    foo(x); // pass x as argument
    cout << *x;
    delete x; // deallocate, not required any more
    return 0;
}

如上所述,不会自动删除任何原始指针。这就是为什么我们不使用原始指针来控制生命周期。我们使用智能指针

下面是用现代c++正确编写的代码片段:

std::unique_ptr<int> foo()
{

    return std::unique_ptr<int>(new int(3));
    // or std::make_unique<int>(3) for c++14

    // function will either std::move the unique_ptr or emplace it efficiently
}

int main()
{
  // x will either be created in-place or move-constructed by foo()
  std::unique_ptr<int> x = foo();

  // potential bug! pointers can be null
  if (x) {
    std::cout << *x;
  }
  else {
    std::cout << "x is null\n";
  }
}

这是一个风格问题。使用shared_ptr等会带来额外的开销。那么,引入最后一段的编辑会破坏这个原本不错的答案吗?@Bathsheba:谁说只有shared_ptr?你有没有把开销与可维护性或异常安全性等因素进行权衡?使用unique_ptr完全没有开销,这是原始海报可以做到的。@phresnel这是一个初学者程序员的答案。在我看来,虽然我可能是错的,但在你开始使用某些东西之前,你应该至少部分地了解它是如何工作的。在您开始使用vector之前,您应该知道它在内部是如何工作的,如果您自己没有实现它,那么至少可以想象您自己实现了它。智能指针也是如此。我不会教那些不能进行基本动态内存管理的程序员在任何地方,任何时候都可以使用智能指针,就像他们应该能够编写的正确代码的替代品一样。a永远不会为整数占用内存。它为指向整数的指针占用内存。您想知道的是,当函数结束时,该内存是否仍然被分配/有效。指针a的情况与此无关。@leems我编辑了我的问题。它现在正确吗?是的。我不想纠正你的措辞,而是想确保你理解正确。这不一定是坏习惯,完全取决于你想做什么。为什么从std::shared_ptr开始,甚至不提更简单的,轻量级std::unique_ptr?@Angew:谢谢你的建议:我在答案中添加了unique_ptr。另一个:纯粹的运气,没有跟踪你:D