我无法理解下面的代码,我希望在堆上创建一个数组并用字符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'关键字传递给我的指针?
由于
答案 0 :(得分:6)
该行
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编号。
答案 1 :(得分:4)
您正在修改代码中的指针。在第一个片段中的第一个循环之后,指针将指向数组的末尾而不是开头。为了使事情更清楚,这也会起作用(不建议但是演示行为):
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";
答案 2 :(得分:1)
您的ptrToHeapArrayPointer名称错误,它只是一个标准的int ptr,您指向与ptrHeapArray相同的位置。如果你将它重命名为currentPositionPtr,你的代码可能对你更有意义。
答案 3 :(得分:0)
当你做ptrHeapArray ++时,它会增加ptrHeapArray的含义。当您打印出数据时,ptrHeapArray不再指向数组的开头。
答案 4 :(得分:0)
问题在于,在第一个示例中,ptrHeapArray最初设置为数组的开头。当您遍历循环时,您正在递增指针,并且在for循环结束时,您指向数组中的最后一个元素。当您通过for循环显示所有值时,您将索引到超过数组末尾的值,因为ptrHeapArray指向您分配的数组中的最后一个元素。
同样重要的是要记住,你应该确保不要使用new运算符丢失你回来的原始指针,这样你就可以正确地释放堆上分配的内存。
答案 5 :(得分:0)
在第一个循环中,您将指针ptrHeapArray
递增,直到数组结束。因此,在执行第一个for循环后,指针指向数组的末尾,而不是在开始时。因此,当您尝试打印数组的内容时,您正在访问无效的内存分配,并且行为将是意外的。在第二种情况下,在为数组赋值之前,您将获取起始地址的副本。因此,当您尝试使用副本打印内容时,它将指向数组的开头。