如何在C ++中增加指针的指针值

时间:2015-12-29 16:49:04

标签: c++ pointers

我一直在阅读指针在C ++中是如何工作的,我试图稍微弄乱它,但程序停止工作。

#include <iostream>
using namespace std;

int main ()
{
  char a[] = "Hello";
  char * b = a;
  char ** c = &b;

  cout << *(b+1) << endl;
  //cout << **(c+2) << endl;
  return 0;
}

如果没有注释注释行,程序将停止使用错误代码:0xC0000005。我做错了什么或是某种错误?

5 个答案:

答案 0 :(得分:3)

下面:

char a[] = "Hello";
char * b = a;

你利用数组来指针衰减。现在b指向a[0]。也就是说,b保存a[0]

的地址

然后

char ** c = &b;

c现在指向b地址,它本身就是一个指针。 c保存b的地址,其中包含a的地址(看看为什么人们现在讨厌指针?)

如果您想从a[0]访问c,首先需要取消引用它:

*c

提供b,然后我们需要取消引用 以返回a[0]

*(*c)

如果您想使用指针算法来访问a[1],您希望增加b,所以:

* C + 1

现在我们的地址为a[1],如果我们要打印,我们需要再次取消引用:

*(*c+1)

当你说:

时,你错误地增加了b的地址而不是地址a[0]
**(c+2)

c保留b的地址,而不是a,因此递增会导致未定义的行为。

答案 1 :(得分:3)

DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/<package name>指向当前堆栈帧上c的地址。

由于指针运算,

b指向堆栈帧上的某个位置。

c + 2然后,您可以访问此位置,并将未指定的字节作为地址。

*(c + 2)现在您尝试访问所说的未指定地址,幸运的是,它崩溃了。

答案 2 :(得分:0)

好的,让我们再试一次。

a是指向数组中第一个元素的指针,在本例中为&#34; H&#34;。 c是指向b的地址的指针,b也是指向第一个元素的指针。

当你将c递增2时,你将指针向前移动两个。所以内存地址前进了两个,但是c只是指向a而不是它自己的指针,因此你处于未知领域。相反,什么可能工作(未经测试):

cout<<*(*c+1)<<endl;

这取消引用c,所以你得到b(或者同样的东西),你将这个指针递增1,它保留在数组中,然后你再次取消引用来访问该值。!

答案 3 :(得分:0)

&b + 2不是有效指针。

为简单起见,我们假设指针只有一个char宽(我们的内存非常非常小)。

假设a存储在地址10,b存储在20,c存储在21。

char* b = a;char* b = &a[0];相同 - 它将数组的第一个元素(10)的位置存储在b中。
char**c = &bb(20)的位置存储在c

看起来像这样:

  a                                       b    c
  10  11  12  13  14  15  16  17  18  19  20   21   22...
| H | e | l | l | o | 0 |   |   |   |   | 10 | 20 | 

从这张图片中可以清楚地看出c + 2是22,这不是有效的地址 取消引用它是未定义的,任何事情都可能发生 - 你的崩溃只是好运。

如果您期待l中的第一个"Hello",它位于a[2],即b[2](或*(b + 2)),即{{} 1}}(或(*c)[2])。

答案 4 :(得分:0)

char a[] = "Hello";
char * b = a;
char ** c = &b;

a和b指向char数组的开头有&#34; Hello&#34;作为它的角色。

所以,让我们从内存位置开始0x100存储Hello。

a是指针,因此它存储一个地址。

a和b都存储此值0x100。但他们的地址是别的。假设a的地址是0x200,b的地址是0x300。

c也是指针。所以它存储了b的地址。 因此,c将地址0x300存储为其值。

c + 1 = 0x304

c + 2 = 0x308

* c:您想要访问存储在0x300的值,这是b的地址。

*(c + 1):您想访问地址0x304

*(c + 2):然后访问0x308,将未指定的字节作为地址。

**(c + 2):取消引用地址0x308。它可能是也可能不是指针变量的地址。因此,解除引用可能是未定义的操作。