【问题标题】:Pointer/Refer to an array?指针/引用数组?
【发布时间】:2014-02-14 16:22:26
【问题描述】:

好的,我正在编写一个对数组执行不同功能的程序。如有必要,阵列将需要更改容量。说明是:

  1. 创建一个新数组。
  2. 将旧数组中的内容复制到新数组中。
  3. 删除旧数组。

这部分是明白的,但我不明白的是如何保持对函数将使用的数组的引用。这是我用于创建新数组并在元素上移动的代码。

  int newSize = m_size*2;

  double *tempArray= new double[newSize];
  for(int i=0; i<m_size-1; i++)
  {
     tempArray[i] = arr[i];
  }

  delete []arr;
  for(int i=0; i<m_size-1; i++)
  {
     arr[i] = tempArray[i];
  }

  delete []tempArray;

 }

所有其他方法都使用 arr 所以我想回顾一下。指针不起作用,因为它只指向第一个元素。如何使用我的 arr 变量来引用数组?

【问题讨论】:

  • 我认为 delete []arr 应该是 arr = new ....

标签: c++ arrays


【解决方案1】:

在 C 和 C++ 中,动态数组通常由指向第一个元素的指针和元素个数表示。所以我假设以下声明:

double *arr;
int m_size;

如果您有任何机会将arr 清除为一个真正的数组double arr[..],那么您将无法执行delete []arr 也无法更改其大小!

那么你的代码应该是这样的:

int newSize = 2*m_size;
double *tempArray= new double[newSize];
for(int i=0; i<m_size-1; i++)
{
   tempArray[i] = arr[i];
}
delete []arr;
arr = tempArray;
m_size = newSize;

但现在我想知道:为什么m_size-1 在循环中?

而且,你可以这样做:

memcpy(tempArray, arr, sizeof(*arr) * m_size)); //or m_size-1?

如果这是一个练习,这一切都很好。对于实际代码,使用std::vector&lt;double&gt;resize() 成员函数几乎总是更好。

【讨论】:

  • ".. 为什么 m_size-1 在循环中?" - 因为m_sizearr现有 分配幅度。 std::copy(arr, arr+m_size, tempArray); 可能更明显,但知道 OP 一开始可能会使用 std::vector&lt;&gt;
  • @WhozCraig:但是数组的最后一个元素(arr[m_size-1] 没有被复制!或者我错过了什么(没有双关语)?
  • 您根本没有错过任何东西。你是绝对正确的。在这么早就在 SO 上发布 cmets 之前,我真的需要至少两杯咖啡。 (顺便说一句,我是这个答案的最初 +1)。
【解决方案2】:

您的代码中有未定义的行为

delete []arr;
for(int i=0; i<m_size-1; i++)
{
   arr[i] = tempArray[i];
}

您删除了 arr 指向的内存,然后分配给循环内已删除的内存。相反,您应该只写:

delete []arr;
arr = tempArray;

整个代码是:

int newSize = m_size*2;

double *tempArray= new double[newSize];
for(int i=0; i<m_size-1; i++) // -1 might be wrong, look below for a comment on this line.
{
   tempArray[i] = arr[i];
}

delete []arr;
arr = tempArray;
m_size = newSize // stolen from the others *cough* since I oversaw the need.
// note that I don't call delete on tempArray.
}

另外我不知道你是如何分配你的第一个数组的,但是如果你让它调用new double[m_size],那么你会想在 for 循环的循环条件中删除-1,因为你正在检查@ 987654326@ 而不是i &lt;= m_size

【讨论】:

  • 这似乎解决了我的问题,谢谢。但是,为什么不删除 tempArray?
  • @marsrover tempArray 只是在复制旧数据时作为指向新数组的临时指针。之后,您将使arr 指向该内存块,因此您仍然需要能够访问它(删除它不会让您仍然可以访问它)。
  • @marsrover 也希望你注意到我的最后一次编辑,我在其中添加了m_size = newSize(其他人已经有了那部分,但我忘了我们必须首先在我的答案中跟踪新的大小)。
【解决方案3】:

你需要在释放 ar 后为其分配内存。

int newSize = m_size*2;

double *tempArray= new double[newSize];
for(int i=0; i<m_size-1; i++)
{
   tempArray[i] = arr[i];
}

delete []arr;
ar = new double[newSize];
for(int i=0; i<m_size-1; i++)
{
   arr[i] = tempArray[i];
}

delete []tempArray;

【讨论】:

  • 过去的整个后半部分delete[] arr; 可以简单地替换为arr = tempArray;。并且您需要将m_size 更新为新尺寸m_size = newSize;
【解决方案4】:
delete []arr;
for(int i=0; i<m_size-1; i++)
{
 arr[i] = tempArray[i];
}

哎呀。删除后请勿访问。并且不要删除,除非它是用 new 分配的。

您根本无法重新分配声明为的数组

int arr[100]

或类似的。

【讨论】:

    【解决方案5】:

    根据您提供的代码,您当前执行的是:

    1. 创建一个新数组 (tempArray)
    2. 将旧 (arr) 数组的内容复制到新 (temp) - (注意 - 如果使新数组比旧数组小会怎样?)
    3. 删除旧数组
    4. 将新值复制回旧数组的已删除剩余部分(注意 - 您已删除 arr,因此您现在无法使用它!)
    5. 删除新数组(所以一切都消失了)

    基本上,您需要修复第 2 步来处理尺寸,并完全摆脱第 4 步和第 5 步 - 您只需要重新分配 arr 即可: arr = tempArray

    【讨论】:

      【解决方案6】:

      您只需声明数组 arr 并将值放入其中。您可以通过其指针 arr 或使用 arr[element_id] 来引用数组。

      【讨论】:

        【解决方案7】:

        你有几个选择:

        1. 采用 C 风格的方法,只存储指向第一个元素的指针,就像你拥有的一样,加上长度。从这两个中你可以计算出你需要的任何东西。

        2. 使用std::vector。它包含一个数组,允许您使用 emplace_back 等函数轻松调整其大小,并可以使用 size 函数告诉您其长度。

        第二种方法当然是首选。如果您使用 C++,通常应该使用 std::vector 而不是原始数组,除非您正在寻找固定大小的数组。在这种情况下使用std::array

        您还可以获得像vector1 = vector2; 一样简单的复制向量的额外好处。

        【讨论】:

        • 我猜这是一个家庭作业,所以“重新发明轮子”才是我们想要的
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-01-08
        • 1970-01-01
        • 1970-01-01
        • 2012-03-25
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多