第一段程序:关于一级指针与二级指针:
int *p = NULL;
int **p2 = &p;
cout << p <<endl;
cout << p2 <<endl;
p输出是0,而p2的输出为xxxx.
这里需要注意的是 NULL 不代表地址0,或者说在windows中代表0. NULL作为一个宏定义,任何系统均有自己的实现方式。(代表一个不可取值的地方)。二级指针是指向一级指针的地址,与NuLL无关。
分水线
--------------------------------------------------------------------------------------------------------------------
第二段程序:关于堆栈修改值的问题
有这么一种用法:
void do_signal(long eip) {
*(&eip) = sa_handle;
}
这是linux源码中的一段程序,让人很费解,这里做简要解释,拆分。
void test(unsigned long p, unsigned long b);
int main()
{
int a = 100;
int b = 200;
int *p = &a;
int *q = &b;
test((unsigned long)p, (unsigned long)q);
cout<< *p<<endl;
}
void test(unsigned long p, unsigned long q) {
//*(&p) = b;
cout<< "p:" <<p<<endl;
cout<< "b:" <<q<<endl;
p = q;
cout<< *(int *)p <<endl;
cout << p <<endl;
}
这里需要解释的是: 在调用test函数时,p,q分别存放a,b的地址入栈。
在函数中改变了p的内容(及指针p的指向),所以这里输出的 *(int *)p的值为200
而跳出函数时,*(int*)p 的值仍为100.
貌似本段程序并没有作用, 其实不然:
若在调用test函数之前,手动为test函数建立参数栈,那么改变的就的确是函数栈的真实内容,当函数弹出时,
若对栈不加以回收,那么实际改变的值就真实的存在了程序中。