【问题标题】:Trouble with pointer arrays and attempting to resize指针数组出现问题并尝试调整大小
【发布时间】:2020-09-12 08:43:20
【问题描述】:

首先,让我说这是一个作业,我不能使用向量。

我试图做的是调整 2 个包含对象的指针数组的大小。数组 custArray 有 3 个元素,数组 gArray 有 1 个。我需要将一个特定对象从 custArray 移动到 gArray 并将其从 custArray 中删除(所以它们都有 2 个元素),所以我创建了 2 个临时数组来更改,然后最终设置为等于 custArray 和 gArray。

void setPreferred(string id, int cSize, int pSize, Customer *custArray, Gold *gArray)
{
   int count = 0;
   Customer *temp1 = new Customer[cSize - 1];
   Gold *temp2 = new Gold[pSize + 1];
   *temp2 = *gArray;
   for(int i = 0; i < cSize; i++)
      {
         if(custArray[i].getID() == id)
            {
               temp2[pSize].setName(custArray[i].getFirstName(), custArray[i].getLastName());
               temp2[pSize].setID(custArray[i].getID());
               temp2[pSize].setTotal(custArray[i].getTotal());
               temp2[pSize].setDiscount(0.5);
               //cout << temp2[1].getName() << " " << temp2[1].getID() << " " << temp2[1].getTotal() << " " << temp2[1].getDiscount() << endl;
            }

         if (custArray[i].getID() != id)
            {
               temp1[count].setName(custArray[i].getFirstName(), custArray[i].getLastName());
               temp1[count].setID(custArray[i].getID());
               temp1[count].setTotal(custArray[i].getTotal());
               count++;
            }
      }
   //cout << temp1[0].getName() << " " << temp1[0].getID() << " " << temp1[0].getTotal() << endl;
   //cout << temp1[1].getName() << " " << temp1[1].getID() << " " << temp1[1].getTotal() << endl;

   delete [] custArray;
   delete [] gArray;

   *custArray = *temp1;
   *gArray = *temp2;
}

2 个原始数组在 main 中定义为

Customer *customerArray = new Customer[customerSize];
Gold *goldArray = new Gold[preferredSize];

数组 temp1 和 temp2 在函数中工作正常,cout 语句打印所有正确信息。但是,当我尝试在 main 中打印 customerArray[1] 的任何成员时,它会显示不正确的信息,并且 goldArray[1] 的成员会抛出 bad_alloc 错误。我想这意味着我删除或重新分配数组的方式有问题。任何帮助将不胜感激。

【问题讨论】:

  • 您的代码有很多问题,但最根本的问题是您希望函数返回新数组,但绝不会返回新数组。您似乎认为*custArray = *temp1; 以某种方式将数组从temp1 复制到custArray,但事实并非如此。 *custArray = *temp1;custArray[0] = temp1[0];完全相同
  • @Siroos 你需要通过引用传递,然后在你的代码的某个地方你需要写custArray = temp1;而不是*custArray = *temp1;
  • @Siroos 总是,总是,当初学者对指针感到困惑时,这是因为他们将指针与指针所指向的内容混淆了。这正是你正在做的。
  • 这又是指针和指针指向的内容之间的混淆。变量temp1 超出范围,但它指向的是动态分配的内存,永远不会超出范围(直到你删除它)。
  • 我不确定我是否理解,不需要指向指针的指针,只需要对指针的引用。可以这样想,假设您想编写一个函数来更改 int 的值,并通过引用传递给函数。现在编写完全相同的代码,只需将int 更改为指针。它将以相同的方式工作。这是关于指针的另一条规则,指针没有什么特别之处。它们的工作方式与任何其他类型的变量相同。

标签: c++ arrays pointers


【解决方案1】:

指针被删除后不能取消引用。如果你这样做,可能会发生意想不到的事情。

【讨论】:

    【解决方案2】:

    首先,*custArray = *temp1 只复制由temp1 指向的单个值,而不是其余的(temp1+1temp1+2 等)。您必须在循环中进行赋值才能复制数组,但从语义上讲,您不应该在这里这样做。

    您还可以在尝试写入之前删除custArray 指向的存储,这是一个UB。

    遍历cSize - 1 对象数组时出现开关错误。您的 Customer 类要么显然不可复制,要么出于某种原因您使用 getters\setters 来复制单个字段而不是复制分配。让我怀疑你是否知道 struct\class 赋值是如何工作的。

    其次,custArray 是您定义函数参数的方式的局部变量,并且您没有在函数之外更改值。通过引用 Customer *&amp;(或 C 风格的 Customer**)传递指针可以解决这个问题,但它很丑陋,并且使代码复杂且容易出错。重新分配会改变内存存储,你必须返回指向新存储的指针

    我恳请您创建类,专门用于处理CustomerGold 的数组,或者更好的是,一些通用的Array 模板可以处理任何元素类并实现基本分配\移动\分配\里面的释放逻辑。您编写的是 C++ 代码,而不是 C 代码,因此禁止使用特定的标准语言组件意味着您必须学习如何实现自己的代码,而不是扔掉它并假装它是不可能的。

    【讨论】:

      【解决方案3】:

      概括地说,这就是您的代码的外观

      // note custArray and gArray passed by reference
      void setPreferred(string id, int cSize, int pSize, Customer*& custArray, Gold&* gArray)
      {
          // allocate the new arrays
          Customer *temp1 = new Customer[cSize - 1];
          Gold *temp2 = new Gold[pSize + 1];
      
          // code to do the copying from custArray and gArray to temp1 and temp2
          // (you still need to write this)
          ...
      
          // delete the old arrays
          delete[] custArray;
          delete[] gArray;
      
          // return the new arrays to the caller
          custArray = temp1;
          gArray = temp2;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-24
        • 1970-01-01
        • 1970-01-01
        • 2019-09-18
        • 2017-04-18
        • 2020-02-21
        • 2012-03-17
        • 1970-01-01
        相关资源
        最近更新 更多