C++ 函数调用中的堆和删除。如何删除本地动态内存?

C++ 函数调用中的堆和删除。如何删除本地动态内存?,c++,dynamic,return,member,delete-operator,C++,Dynamic,Return,Member,Delete Operator,我知道已经动态分配并使用堆的内存需要使用delete手动删除。如果在将超出范围的类函数中创建动态对象,是否也是这种情况?这里是一个片段 Fraction* Fraction::add(const Fraction* fr) const{ int gcd; Fraction* temp; gcd = gcdRecur(num * fr->denom + fr->num * denom, deno

我知道已经动态分配并使用堆的内存需要使用delete手动删除。如果在将超出范围的类函数中创建动态对象,是否也是这种情况?这里是一个片段

    Fraction* Fraction::add(const Fraction* fr) const{ 
      int gcd;
      Fraction* temp;

      gcd = gcdRecur(num * fr->denom + fr->num * denom, 
                     denom * fr->denom);

      temp = new Fraction((num * fr->denom + fr->num * denom) / gcd, 
                          (denom * fr->denom) / gcd);

      return temp;
   }
在这种情况下,temp是一个指向使用“new”(右?)的france类型的动态对象的指针。如果我将此指针返回到调用类函数“add”的位置,是否需要删除本地指针“temp”?如果是,我如何才能做到这一点

编辑:我对在这个类成员中使用new的(错误的)解释是因为分数对象是通过指向分数的指针实例化的(如下所示):

看起来很糟糕。。。以下是addMenu的标题:

     void addMenu(const FractionTeddyD*, const FractionTeddyD*, FractionTeddyD**);

编辑#2:不使用“新建”解决。在C++中指针是通过值传递的,这意味着你可以在指针所在的任何地方删除对象(只要它还没有被删除)。因为它们基本上只存储一个地址,所以这很好,因为当调用delete时,它知道在哪里以及如何释放内存

在您的情况下,您将在函数之外删除它,否则返回它就没有意义了。为了避免自己管理内存,实际上应该使用

std::unique_ptr Fraction::add(const Fraction*fr)const{
int gcd;
gcd=gcdRecur(num*fr->denom+fr->num*denom,
denom*fr->denom);
std::unique_ptr ptr(新分数((num*fr->denom+fr->num*denom)/gcd,
(denom*fr->denom)/gcd);
返回ptr;
}

使用这种样式将省去许多头痛,现在被认为是C++中的惯用用法。参数

fr
也可以作为
唯一\u ptr
传递,要采用这种编码方式,您还需要了解哪个表示没有唯一所有权的ptr(可以存在多个)


然而,真正的问题是,当您在堆上创建对象时,没有将指针与对象的地址一起保存。然后该对象将丢失且无法释放。

您可以使用智能指针,如
std::unique\u ptr
std::shared\u ptr

 std::unique_ptr<Fraction> Fraction::add(...) const { 

      ...

      std::unique_ptr<Fraction> temp (new Fraction(...));

      return temp;
  }
std::unique_ptr Fraction::add(…)const{
...
标准:唯一的ptr温度(新分数(…);
返回温度;
}

你可以不用担心删除内存。

它确实需要删除,否则内存会泄漏。您不能在本地删除它,因为调用方需要在函数返回后使用它。一旦不再需要,调用方必须将其删除。显然,这很容易出错,这就是为什么您应该始终使用它来管理动态资源的原因

在这种情况下,您应该将返回类型更改为智能指针,如
std::unique\u ptr

 std::unique_ptr<Fraction> Fraction::add(...) const { 

      ...

      std::unique_ptr<Fraction> temp (new Fraction(...));

      return temp;
  }

另一方面,为什么在这里使用
new
?返回一个值会更简单,而且几乎肯定会更快。

一旦停止使用内存,就需要删除它。除非编译器具有内置内存清除系统并将其嵌入到*.exe文件中,否则不会为您释放内存

另一方面:您可能不想在
add
函数中分配新内存。试着读一下。当您查找该术语时,您可能会注意到
operator+
通常返回对该类实例的引用。我认为这可能是解决你问题的更好办法


如果您确实需要指针,并且不想为何时删除指针而烦恼,那么有许多类存储智能指针,如
std::shared_ptr
()

您对可能很小的类分数的设计可能是不好的

具有:

class Fraction {
    public:
    int numerator;
    int denominator;
};
您可以通过引用传递并通过值返回:

Fraction Fraction::add(const Fraction& fr) const;

只是玩简单的代码!但是,如果我主要是创建指向我将创建的对象的分数指针(因为我有一个菜单,并且我不希望在用户选择初始化之前初始化分数对象),我仍然可以传递对指针的引用(如下所示?:const-Fraction*&fr)并将分数的返回类型:add(const-Fraction&fr)常数;仍然有效?为什么没有无效分数{0,0}的向量或分数的映射?无法将向量或映射用于此赋值!(不幸的是)我需要在一个独立的“菜单”函数中创建指向分数对象的指针,该函数被设置为Null,直到用户选择初始化分数对象。当用户想要对已初始化的分数进行加/减/乘时,必须从使用独立/member/member operator函数的选项中调用额外的子菜单。我想我在将这些指针传递到子菜单时遇到了问题(我传递它们的方式是:…(常量分数*…)。这可能就是我开始时遇到问题的原因。在这种情况下,我不认为我可以按值返回,除非我在子菜单中创建本地对象,然后将这些值分配给我已通过的分数指针…这会比我现在拥有的更好吗?此外,出于此分配的目的,我不能使用智能poi安特。
Fraction Fraction::add(const Fraction& fr) const;