在堆上创建数组并用指针寻址它们
Posted
技术标签:
【中文标题】在堆上创建数组并用指针寻址它们【英文标题】:Creating arrays on the heap and addressing them with pointers 【发布时间】:2009-06-22 11:53:45 【问题描述】:我无法理解以下代码,我希望在堆上创建一个数组并用从 9 到 0 的字符填充它(我知道我可以像普通堆栈数组一样索引数组[] 符号来做到这一点,但我这样做是为了更深入地理解指针):
int *ptrHeapArray = new int[10];
for(int f=9; f>=0 ;f--)
*ptrHeapArray = f;
ptrHeapArray++;
for(int f=0; f<10; f++)
cout << ptrHeapArray[f] << "\n";
它打印出完全出乎意料的值。
据我了解,“new”命令会在堆上创建一个数组,并向我发送一个指向该数组所在地址的指针。由于我分配的指针 (ptrHeapArray) 是 int 大小,我认为我可以使用指针后递增来导航数组。但是结果表明我的假设是错误的。
这让我想到,也许'new'关键字传回的指针只是指向整个数组的指针,并且由于某种原因不能用于单步遍历数组。 所以我尝试创建另一个指向“new”关键字返回的指针的指针,并用它来填充我的数组:
int *ptrHeapArray = new int[10]; //array to hold FRANK data in 32 bit chunks
int *ptrToHeapArrayPointer = ptrHeapArray;
for(int f=9; f>=0 ;f--)
*ptrToHeapArrayPointer = f;
ptrToHeapArrayPointer++;
for(int f=0; f<10; f++)
cout << ptrHeapArray[f] << "\n";
这很好用。 谁能向我解释为什么我必须这样做并且不能只使用通过“new”关键字传递给我的指针?
谢谢
【问题讨论】:
【参考方案1】:线
ptrHeapArray++;
在您的第一个 for 循环中增加指针,使其不再指向数组的开头。
线
int *ptrHeapArray = new int[10];
为 10 个整数分配内存并将 ptrHeapArray 指向该内存的开头。然后在你的 for 循环中移动这个指针。当 ptrHeapArray 指向第三个整数时:
[0] [1] [2] [3] [4]
^ ^ ^
orig. | |
| +-- ptrHeapArray[2]
|
+-- ptrHeapArray now points here
然后 ptrHeapArray[2] 会给你原来编号为 4 的位置的整数。
【讨论】:
它基本上破坏了数组的头部 @Nathan:别这么说。您没有区分指针和它指向的内容。这是新程序员经常发现的一个区别。 “数组的头部”根本没有被破坏(覆盖)。它没有改变。根本没有指向它的指针。【参考方案2】:您正在修改代码中的指针。在第一个 sn-p 中的第一个循环之后,指针将指向数组的末尾而不是开头。为了让事情更清楚,这也可以(不建议但演示了行为):
int *ptrHeapArray = new int[10];
for(int f=9; f>=0 ;f--)
*ptrHeapArray = f;
ptrHeapArray++;
ptrHeapArray -= 10; // reset the pointer to its original location
for(int f=0; f<10; f++)
cout << ptrHeapArray[f] << "\n";
【讨论】:
【参考方案3】:您的 ptrToHeapArrayPointer 命名错误,它只是一个标准的 int ptr,您已指向与 ptrHeapArray 相同的位置。如果您将其重命名为 currentPositionPtr,您的代码可能对您更有意义。
【讨论】:
【参考方案4】:当您执行 ptrHeapArray++ 时,它会增加 ptrHeapArray。当你来打印出数据时,ptrHeapArray 不再指向数组的开头。
【讨论】:
【参考方案5】:问题在于,在您的第一个示例中,ptrHeapArray 最初设置为数组的开头。当您遍历循环时,您将递增指针,并且在 for 循环结束时,您将指向数组中的最后一个元素。当您通过 for 循环显示所有值时,您将索引到数组末尾之后的值,因为 ptrHeapArray 指向您分配的数组中的最后一个元素。
同样重要的是要记住,您可能应该确保不要丢失使用 new 运算符返回的原始指针,以便您可以正确释放在堆上分配的内存。
【讨论】:
【参考方案6】:在第一个循环中,您将指针 ptrHeapArray
递增直到数组末尾。因此,在执行第一个 for 循环后,您的指针指向数组的末尾而不是开头。因此,当您尝试打印数组的内容时,您正在访问无效的内存分配,并且行为将是意外的。在第二种情况下,您在将值分配给数组之前获取起始地址的副本。因此,当您尝试使用副本打印内容时,它将指向数组的开头。
【讨论】:
以上是关于在堆上创建数组并用指针寻址它们的主要内容,如果未能解决你的问题,请参考以下文章