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

Posted

技术标签:

【中文标题】在堆上创建的变量,指向同一个变量的2个指针有不同的地址?【英文标题】:Variable created on the heap, 2 pointers pointing to same variable have different addresses? 【发布时间】:2010-11-28 04:19:05 【问题描述】:

我刚刚学会了栈和堆的区别。在创建一个为我在堆上动态分配内存的函数后,我返回指针并显示(在函数内外)每个指针的地址和值。

值是相同的,这是我的预期,但是堆上同一块内存的地址是不同的,这是我没想到的。

为什么? pHeap2 和 pTemp 不应该指向同一个地址吗?

#include <iostream>
using namespace std;

int* intOnHeap(); // returns an int on the heap
int main()

 int* pHeap = new int; // new operator allocates memory on the heap and returns its address
       // 'new int' allocates enough memory on heap for one int and returns the address on the heap for that chunk of memory
       // 'int* pHeap' is a local pointer which points to the newly allocated chunk of memory
 *pHeap = 10;
 cout << "*pHeap: " << *pHeap << "\n\n";

 int* pHeap2 = intOnHeap();
 cout << "pHeap2:\n-----------" << endl;
 cout << "Address:\t" << &pHeap2 << "\n";
 cout << "Value:\t\t" << *pHeap2 << "\n\n";

 cout << "Freeing memory pointed to by pHeap.\n\n";
 delete pHeap;

 cout << "Freeing memory pointed to by pHeap2.\n\n";
 delete pHeap2;

// get rid of dangling pointers
    pHeap = 0;
    pHeap2 = 0;

 system("pause");
 return 0;


int* intOnHeap()

 int* pTemp = new int(20);
 cout << "pTemp:\n-----------" << endl;
 cout << "Address:\t" << &pTemp << "\n";
 cout << "Value:\t\t" << *pTemp << "\n\n";
 return pTemp;

输出:

*pHeap: 10

pTemp:
-----------
Address:        0042FBB0
Value:          20

pHeap2:
-----------
Address:        0042FCB4
Value:          20

Freeing memory pointed to by pHeap.

Freeing memory pointed to by pHeap2.

Press any key to continue . . .

【问题讨论】:

【参考方案1】:

您报告的是指针的地址,而不是指针指向的地址。当然pTemppHeap2的指针地址会不同;这些是碰巧指向内存中相同地址的不同指针。删除 &amp; 前缀 pTemppHeap2 以查看您期望的结果。

图片是这样的:

0042FBB0           0042FBC0     0042FCB4
------------       ------       ------------
| 0042FBC0 |------>| 20 |<------| 0042FBC0 |
------------       ------       ------------
pTemp                           pHeap2

在这里,&amp;pTemp0042FBB0&amp;pHeap20042FCB4。我为pTemppHeap2 指向的地址编了一个地址(当然,结果可能因运行而异),如果你删除&amp; 前缀pTemppHeap2 然后在每种情况下,您都会看到 0042FBC0 被打印出来。

【讨论】:

老兄,非常感谢。我想我知道 &var 给出了那个变量的地址,但是我忘记了指针会有自己的地址,并且指向不同的地址。我修改了我的代码并添加了: cout @shadowprotocol:是的,就是&amp;pTemp&amp;pHeap2是指针,就是图中左右框上方的地址。 为什么我不能在我的 cmets 中添加格式和段落?太丑了,上图。 @shadowprotocol:注释解析器会忽略段落和许多其他类型的间距。您可以将代码包装在反引号 ` 中以格式化为等宽字体。【参考方案2】:

是的,pTemppHeap2 应该相同。但是&amp;pTemp&amp;pHeap2 是不同的。这是因为&amp; 运算符返回一个指向其操作数的指针。所以pTemp 是指向int 的指针,而&amp;pTemp 是指向int 的指针。

【讨论】:

【参考方案3】:

&amp;pHeap2 不返回指针的值,而是返回指针的地址。这是因为&amp;,在这种情况下表示“地址”。

即在内存中的 0042FCB4 处,有一个指向 0042FBB0 的指针(即在大端环境中,您会在 0042FCB4 处看到 00 42 FB B0)。

【讨论】:

以上是关于在堆上创建的变量,指向同一个变量的2个指针有不同的地址?的主要内容,如果未能解决你的问题,请参考以下文章

Go 语言中的变量究竟是分配在栈上还是分配在堆上?

C++ 在堆上分配相同类型的变量会花费截然不同的时间

java语言中,类的成员变量分配在哪个内存区?

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

返回在堆上分配的类的实例(C++)[关闭]

1-认识c指针