指针/引用数组?

Posted

技术标签:

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

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

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

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

  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 .... 【参考方案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】:

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

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

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

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

你有几个选择:

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

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

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

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

【讨论】:

我猜这是一个家庭作业,所以“重新发明***”才是我们想要的

以上是关于指针/引用数组?的主要内容,如果未能解决你的问题,请参考以下文章

取消引用数组指针

指针和引用指针数组和数组指针

指针/引用数组?

5数组指针和引用:数组

通过引用返回指针数组

指向指针的指针如何能够引用数组