2

我无法理解以下代码,我希望在堆上创建一个数组并用字符 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”关键字传递给我的指针?

谢谢

4

6 回答 6

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 的位置的整数。

于 2009-06-22T11:56:05.893 回答
5

您正在修改代码中的指针。在第一个片段中的第一个循环之后,指针将指向数组的末尾而不是开头。为了使事情更清楚,这也可以工作(不建议但演示了行为):

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";
于 2009-06-22T11:56:51.397 回答
1

您的 ptrToHeapArrayPointer 命名错误,它只是一个标准的 int ptr,您已指向与 ptrHeapArray 相同的位置。如果您将其重命名为 currentPositionPtr,您的代码可能对您更有意义。

于 2009-06-22T12:01:12.917 回答
0

当您执行 ptrHeapArray++ 时,它会增加 ptrHeapArray。当您打印出数据时,ptrHeapArray 不再指向数组的开头。

于 2009-06-22T11:58:05.107 回答
0

问题是,在您的第一个示例中,ptrHeapArray 最初设置为数组的开头。当您遍历循环时,您将递增指针,并且在 for 循环结束时,您将指向数组中的最后一个元素。当您通过 for 循环显示所有值时,您正在索引超出数组末尾的值,因为 ptrHeapArray 指向您分配的数组中的最后一个元素。

同样重要的是要记住,您可能应该确保不要丢失使用 new 运算符返回的原始指针,以便您可以正确释放在堆上分配的内存。

于 2009-06-22T11:59:48.117 回答
0

在第一个循环中,您将指针递增ptrHeapArray到数组末尾。因此,在执行第一个 for 循环后,您的指针指向数组的末尾而不是开头。因此,当您尝试打印数组的内容时,您正在访问无效的内存分配,并且行为将是意外的。在第二种情况下,您在将值分配给数组之前获取起始地址的副本。因此,当您尝试使用副本打印内容时,它将指向数组的开头。

于 2009-06-22T12:02:13.680 回答