指针/引用数组?
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<double>
和resize()
成员函数几乎总是更好。
【讨论】:
".. 为什么 m_size-1 在循环中?" - 因为m_size
是arr
的现有 分配幅度。 std::copy(arr, arr+m_size, tempArray);
可能更明显,但知道 OP 一开始可能会使用 std::vector<>
。
@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 <= m_size
。
【讨论】:
这似乎解决了我的问题,谢谢。但是,为什么不删除 tempArray? @marsrovertempArray
只是在复制旧数据时作为指向新数组的临时指针。之后,您将使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;
一样简单的复制向量的额外好处。
【讨论】:
我猜这是一个家庭作业,所以“重新发明***”才是我们想要的以上是关于指针/引用数组?的主要内容,如果未能解决你的问题,请参考以下文章