内存单元和 C++ 指针
Posted
技术标签:
【中文标题】内存单元和 C++ 指针【英文标题】:memory cells and c++ pointers 【发布时间】:2017-04-06 06:33:38 【问题描述】:我目前想知道关于 c++ 中的指针的一些事情。例如,指针返回变量的内存地址。所以如果我们说,我们想要一个整数的内存地址,我们通常有一个 32 位的长度。
当我们说一个内存单元的大小是 1 字节时,我需要 4 个单元来表示一个整数(4x8 位 = 32 位)。因此,假设我有一个指针地址,例如:0x613c20
一个整数 (int a = 10;
)。
当此地址指向整个内存中的 4 个单元格之一时,为什么当我将单元格增加 +1 时会得到另一个值?我仍然会得到相同的值,因为我仍在 4 个单元格之一内?
非常感谢。
编辑:
我想我在第一次发帖时不太清楚:
我不是说我把指针增加了pointer++
;
我在调试器中,通过添加 +1 来操作整数的内存地址,例如:
0x1 -> 0x2。
也就是说:
int a = 10;
*int b = &a; // 0x1
*0x1 -> 10
*0x2 -> 1203104
当 Integer 大小为 4 字节长时,为什么我这里没有 10?
【问题讨论】:
这取决于您所说的“增加单元格”是什么意思。如果你的意思是指针,你应该查看指针增量是如何工作的。否则,您应该查看整数在内存中的确切存储方式。 以二进制形式考虑这些单元格。然后你会注意到,即使开始在这 4 个单元格内,当你采取后续 4 个单元格时,如果它们被填充并有随机结果,你将超出范围并获得随机值。 从 lisp 或 snobol4 或 c 中搜索“atom interface”。 这个单元概念在 C++ 中有一个名字。它被称为字节。 【参考方案1】:当你增加/减少一个指针时,内存地址会“增加/减少”指针被声明为的对象类型的长度(例如,它会指向相同类型的下一个/上一个对象,如果它会是一系列相同类型的对象)
一个小例子:
#include <iostream>
using std::cout;
using std::endl;
int main()
int i = 5;
int* p_i = &i;
short c = 'a';
short* p_c = &c;
cout << "\npointer to int (4 bytes)\n";
cout << "adress: " << p_i << " ";
cout << "value: " << *p_i << endl;
++p_i;
cout << "adress: " << p_i << " ";
cout << "value: " << *p_i << endl;
++p_i;
cout << "adress: " << p_i << " ";
cout << "value: " << *p_i << endl;
++p_i;
cout << "adress: " << p_i << " ";
cout << "value: " << *p_i << endl;
++p_i;
cout << "\npointer to short (2 bytes)\n";
cout << "adress: " << p_c << " ";
cout << "value: " << *p_c << endl;
++p_c;
cout << "adress: " << p_c << " ";
cout << "value: " << *p_c << endl;
++p_c;
cout << "adress: " << p_c << " ";
cout << "value: " << *p_c << endl;
++p_c;
cout << "adress: " << p_c << " ";
cout << "value: " << *p_c << endl;
++p_c;
return 0;
以上代码输出:
pointer to int (4 bytes)
adress: 0x28ff24 value: 5
adress: 0x28ff28 value: 2686754
adress: 0x28ff2c value: 2686764
adress: 0x28ff30 value: 2686800
pointer to short (2 bytes)
adress: 0x28ff22 value: 97
adress: 0x28ff24 value: 5
adress: 0x28ff26 value: 0
adress: 0x28ff28 value: -216
正如您所看到的,指向 short 的指针以 2 步“增加”,因为 short 占用 2 个字节的内存,而 int 更长,占用 4 个字节(在我的系统上)。
我建议参考有关数据类型长度的文档(它们可能因系统和编译器而异)和指针以获取更多信息。
【讨论】:
啊,谢谢。问题是:我没有将它增加 ++,我使用调试器和观察点来查找变量的地址并通过添加 +1 来增加它,所以地址从:0x28ff24 -> 0x28ff25 我得到了另一个值,通过取消引用它们。那为什么会这样呢?通常我仍然会得到相同的值,因为我仍然“在”同一个变量中? 很高兴我们对这个问题有了更多的了解。就您而言,我相信这取决于您使用的调试器。不过我有一种预感,它很可能会从您设置的新位置读取四个字节(类型的长度),从而将它在该内存片中找到的数据解释为一个完全不同的变量。例如。它现在读取 0x28ff25 到 0x28ff28 而不是 0x28ff24 到 0x28ff27 在您更改第一个“单元格”的地址之前。不过,我建议在您的调试器中进行测试。【参考方案2】:你正在做的是指针运算。将指针(而不是值)加一的结果取决于指针的类型。在您的示例中,实际地址不是增加 1,而是增加 4(或 sizeof(int))。此外,没有像
这样的东西我仍然会得到相同的值,因为我仍在 4 个单元格之一中
【讨论】:
以上是关于内存单元和 C++ 指针的主要内容,如果未能解决你的问题,请参考以下文章