我有一个指向结构数组的指针的问题。
我声明并初始化具有成员val
的结构的三个点。
我创建了一个指向结构指针数组的指针arr
。
然后创建指向指针pa
的指针arr
和指向pa1
的指针pa
。
当我尝试使用arr
提取pa1
的第二个元素时遇到问题。
Main.cpp
#include<iostream>
#include<cstdio>
struct a{
int val;
};
int main(){
// create structures
a *a1 = new a;
a1->val = 5;
a *a2 = new a;
a2->val = 3;
a *a3 = new a;
a3->val = 4;
a *arr[3] = { a1, a2, a3 };
a **pa = arr;
std::cout << "Using pa:\n";
std::printf( "1st val: %d\n", ((*pa)+0)->val );
std::printf( "1st pos: %p\n", ((*pa)+0) );
std::printf( "2nd val: %d\n", (*(pa+1))->val );
std::printf( "2nd pos: %p\n", (*(pa)+1) ); // modified
std::cout << std::endl << std::endl;
// a pointer to pa's value
a *pa1 = *pa;
std::cout << "Using pa1:\n";
std::printf( "1st val: %d\n", pa1->val );
std::printf( "1st pos: %p\n", pa1 );
std::printf( "2nd val: %d\n", (pa1+1)->val );
std::printf( "2nd pos: %p\n", pa1+1 );
delete [] arr;
delete pa;
delete pa1;
return 0;
}
然后我得到如下结果,
Using pa:
1st val: 5
1st pos: 0000000000e761e0
2nd val: 3
2nd pos: 0000000000e761e4
Using pa1:
1st val: 5
1st pos: 0000000000e761e0
2nd val: 0
2nd pos: 0000000000e761e4
问题是为什么2nd val
的pa1
不是3而是0?
pa
和pa1
都指向相同的地址0000000000e761e4
。
UPDATE
// modified
行应为std::printf( "2nd pos: %p\n", *(pa+1) );
。
结果变成如下
Using pa:
1st val: 5
1st pos: 0000000000ee61d0
2nd val: 3
2nd pos: 0000000000ee61f0
Using pa1:
1st val: 5
1st pos: 0000000000ee61d0
2nd val: 0
2nd pos: 0000000000ee61d4
2nd pos
的pa
与pa1
的实际上不同。
现在的问题是如何使用arr
从pa1
中获取第二个元素?
pa
和pa1
似乎都指向相同的地址0000000000e761e4
。
但是它们是不同的类型。因此,+1
给出了一个不同的地址。
pa1
是a*
类型,因此pa1+1
是reinterpret_cast<a*>(reinterpret_cast<unsigned char*>(pa1)+sizeof(a))
。注意,我们剥离了一层间接层来计算偏移量。
[pa
是a**
类型,因此pa1+1
是reinterpret_cast<a**>(reinterpret_cast<unsigned char*>(pa)+sizeof(a*))
。
由于reinterpret_cast<unsigned char*>(pa)==reinterpret_cast<unsigned char*>(pa1)
,但是sizeof(a)!=sizeof(a*)
,我们得到了不同的结果。
事实是pa1
不是a
数组中的第一个地址!因此,此计算是错误的。