在堆上创建数组并使用指针对它们进行寻址

时间:2009-06-22 11:53:45

标签: c++ pointers heap new-operator

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

由于

6 个答案:

答案 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循环后,指针指向数组的末尾,而不是在开始时。因此,当您尝试打印数组的内容时,您正在访问无效的内存分配,并且行为将是意外的。在第二种情况下,在为数组赋值之前,您将获取起始地址的副本。因此,当您尝试使用副本打印内容时,它将指向数组的开头。