0

最初,我的实验室传递了三个参数: addFractionJesseR(*lFrac, *rFrac, **resFrac); 但我刚刚发现我不能传递三个参数。我不得不将其更改为 **resFrac = addFractionJesseR(*lFrac, *rFrac); 现在我在编译时遇到问题。我知道我的指针和双指针在某个地方超出了范围,但我就是不知道在哪里。调试器指向第二行作为问题:

FractionJesseR& FractionJesseR::operator=(const FractionJesseR& arg) {
  num = arg.num;
  denom = arg.denom;
  return *this;
}

由以下方式调用:

FractionJesseR& addMenu(FractionJesseR* lFrac, FractionJesseR* rFrac) {
  int option;
  FractionJesseR** resFrac = new FractionJesseR*();
......
    case 2:
      cout << "Calling add() --\n\n";
      **resFrac = addFractionJesseR(*lFrac, *rFrac);
      break;
    ......

**resFrac = addFractionJesseR(*lFrac, *rFrac); 最初是 addFractionJesseR(*lFrac, *rFrac, **resFrac);

由以下方式调用:

void displayMenu() {
  int option;
  FractionJesseR *lFrac = nullptr;
  FractionJesseR *rFrac = nullptr;
  FractionJesseR *resFrac = nullptr;
......
    case 2:
      cout << "  Adding Option --\n\n";
      if (lFrac == nullptr && rFrac == nullptr) {
        cout << "    Not a proper call as no Fractions are available!\n\n";
      }
      else {
        *resFrac = addMenu(lFrac, rFrac);
      }
      break;

*resFrac = addMenu(lFrac, rFrac) 最初是 addMenu(lFrac, rFrac, &resFrac)

(是的,我确实对我的所有指针都调用了 delete,我还是 Stack Overflow 的新手,并且正在学习只放置相关的代码片段)我需要帮助来指引我正确的方向。我认为我的指针超出了 addMenu 或 displayMenu 某处的范围......也许我取消引用了一个错误的双指针?

任何帮助将不胜感激!

编辑:

FractionJesseR& addFractionJesseR(FractionJesseR& lFrac, FractionJesseR& rFrac) {
  int n = 0;
  int d = 0;
  FractionJesseR *resFrac = nullptr;

 // Adding the fractions
 n = (&lFrac)->getNum() * (&rFrac)->getDenom() + (&lFrac)->getDenom() *
    (&rFrac)->getNum();
  d = (&lFrac)->getDenom() * (&rFrac)->getDenom();

  resFrac = new FractionJesseR(n / gcd(n, d), d / gcd(n, d));

  if (d < 0) {
    d = -d;
    n = -n;
  }

  return *resFrac;
}
4

1 回答 1

1

您在内存管理方面遇到问题。

我假设您使用的是某个版本的 Visual Studio。调试器通常会标记要执行的下一行,所以你会崩溃

num = arg.num;

发生这种情况是因为this为空,因为

FractionJesseR** resFrac = new FractionJesseR*();

在空闲存储上分配一个指针(这是不寻常的)并将其初始化为 0(因为括号)。这个:

**resFrac

首先取消引用resFrac,给出一个空指针,然后再次取消引用。取消引用空指针是未定义的行为。在您的情况下,它会导致第一条语句的赋值运算符崩溃。

显而易见的解决方案是停止使用指针和手动内存管理。充其量,使用对象:

FractionJesseR resFrac
// ...
resFrac = addFractionJesseR(*lFrac, *rFrac);

在最坏的情况下,使用智能指针:

auto resFrac = std::make_unique<FractionJesseR>();
// ...
*resFrac = addFractionJesseR(*lFrac, *rFrac);

你不想做什么(除非你因为这是一项任务而被迫这样做,在这种情况下我会质疑动机):

auto resFrac = new FractionJesseR;
// ...
*resFrac = addFractionJesseR(*lFrac, *rFrac);
// ...
delete resFrac;

addFractionJesseR()正在返回对在免费存储上分配的值的引用。你要在哪里删除它?每一个都new必须匹配一个delete.

如果你真的想要一个手动内存管理的例子,你不应该混合指针和引用:

FractionJesseR* addFractionJesseR(FractionJesseR* a, FractionJesseR* b)
{
    auto n = a->getNum() * b->getDenom() + a->getDenom() * b->getNum();
    auto d = a->getDenom() * b->getDenom();

    if (d < 0)
    {
        d = -d;
        n = -n;
    }

    return new FractionJesseR(n / gcd(n, d), d / gcd(n, d));
}

FractionJesseR* addMenu(FractionJesseR* a, FractionJesseR* b)
{
    // ...
    FractionJesseR* resFrac = addFractionJesseR(a, b);
    // ...
    return resFrac;
}

void displayMenu()
{
    // ...
    FractionJesseR *resFrac = addMenu(lFrac, rFrac);
    // ...
    delete resFrac;
}

请注意,分配的指针addFractionJesseR()返回到addMenu(),返回到displayMenu(),删除它。

于 2015-05-11T04:47:39.373 回答