【问题标题】:what is pointer past the end of an object means?超过对象末尾的指针是什么意思?
【发布时间】:2014-03-17 23:45:59
【问题描述】:

在 C++ Primer 第 2 章“变量和基本类型”中,它说:

指向对象的指针和超过不同对象末尾的指针有可能保持相同的地址。

我不是母语人士,我认为这就是为什么我对“一个指针超过对象末尾的指针”这句话有点困惑。谁能告诉我这是什么意思?

【问题讨论】:

  • char c[3]; char* p = c + 3; p 是一个超过数组 c 末尾的指针
  • 对于任何数组,获取指向其最后一个元素的指针,然后加 1。这将是一个指针,在末尾之后。

标签: c++


【解决方案1】:

表示之后

int a[] = { 1, 2 };
float b;

(void *) &a[2] == (void *) &b 可能比较为真。

&a[2](或等效的a+2)是一个刚刚超过a 末尾的指针,因为数组只包含索引为0 和1 的元素。

通常,超出范围的数组索引是完全无效的(不允许访问 a[2],甚至计算 &a[3] 也是如此),但是对于计算刚刚超过数组末尾的地址有一个特殊的例外,因为事实证明,这非常有用,例如在迭代数组时,您需要一个结束值来知道何时停止循环。

【讨论】:

  • thx man!,这正是我想知道的,但你能解释一下 (void *) 吗?我不太明白这部分答案
  • 正式地,&a[2] 是未定义的行为。将指针移到末尾的唯一合法方法是a + 2。
  • @JamesKanze 意图是定义行为。 C 已经正式对其进行了定义,对于 C++,即使标准与意图不匹配,也已明确声明了该意图。
  • @libra 没有对void * 的强制转换,您可以在int * 和float * 之间进行比较。我本可以使用 int b; 作为示例,在这种情况下不需要强制转换,但我想强调它可以发生,无论类型如何。
  • @hvd:没错。所以,总而言之,目前,正是詹姆斯所说的。
【解决方案2】:

假设您有一个数组int foo[5] = {1,2,3,4,5};。它在内存中的布局是这样的:

-----------
|1|2|3|4|5|
-----------

有一个指向数组任何成员的指针是合法的;但指向数组末尾一个的指针也是合法的(通常表示在使用迭代器执行 STL 算法时它已到达数组末尾)——尽管它不是取消引用该指针是合法的。像这样:

-------------
|1|2|3|4|5|?|
-------------
 ^         ^
 |         |
 p         q

p 是指向数组的指针; q 是一个过去的指针。

现在,假设您还有一个数组 const char bar[3] = "Hi";。有可能这两个数组在内存中是相邻分配的,如下所示:

<--foo---> <-bar->
-----------------
|1|2|3|4|5|H|i|0|
-----------------
 ^         ^
 |         |
 p         q

那么q 既是foo 的一个过去端,也指向bar[0] 的物理位置。

【讨论】:

【解决方案3】:

“过去”表示“对指针进行+1 操作”。以下代码生成:

0x7ffffcf6a848
0x7ffffcf6a84c
0x7ffffcf6a84c

如您所见,“过去一”的地址,即&amp;a + 1与&amp;b相同。

    int a = 2; 
    int b = 3;
    cout<< &a << endl << &a + 1 << endl << &b <<endl;

【讨论】:

  • 不,它没有。它的意思是“对指针进行 +1 操作,这样您就不再在它所指向的数据的范围内,而只是在一个元素内”。
  • @LightnessRacesinOrbit 问题中的整个句子,即“...结束后的一个”就是您在评论中所说的。我只是回答了“过去”的意思。它的字面意思是“指针上的 +1 操作”。 :-)
  • 不,再一次,它确实没有。 “过去”意味着您超出了基础对象一个。任意 +1 操作都是一个increment;你可以称它为“one up”,但没有其他人这样做! int ar[3] = {}; int* ptr = ar; ar+1; // NOT "one past"!
  • 哈哈我只是在听“Let It Go”。很奇怪。
  • @LightnessRacesinOrbit 这仅取决于您如何理解英语中的“过去”。 13 年 2 月 12 日过去一天。因此,在我看来,您只是在谈论英语而不是 C++ 编程。
猜你喜欢
  • 2017-02-08
  • 2012-05-07
  • 2012-10-31
  • 1970-01-01
  • 1970-01-01
  • 2015-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多