在堆上创建数组并用指针寻址它们

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

【讨论】:

以上是关于在堆上创建数组并用指针寻址它们的主要内容,如果未能解决你的问题,请参考以下文章

在堆上创建的变量,指向同一个变量的2个指针有不同的地址?

使用类模板时在堆上创建对象

在堆上存储 3D 数组作为结构成员

在堆上分配的对象

用指针创建静态数组?

C++ MovieList 数组和指针