例子一:
int main(char argc,char* argv[ ])
{
char *p;
p=0x080000;
*p=3; //1
return 0;
}
程序在1处奔溃,因为p的地址是任意分配的,不知道系统是否已经使用这个地址,这么做是危险的。
正确的做法:
int main(char argc,char* argv[ ])
{
char *p,i;
p=&i;
*p=3; //1
return 0;
}
这样程序才不会奔溃。
例子二:
struct S {
int i;
int *p;
}
int main(char argc,char* argv[ ])
{
S s;
int *p=&s.i;
p[0]=4;
p[1]=3;
s.p=p;
s.p[1]=1;//1
s.p[0]=2;//2
return 0;
}
程序将在2处奔溃,原因是s.p[1]=*(&s.i+1)=s.p,所以s.p[1]与s.p指向同个内存空间,s.p[1]=s.p=1即s.p[0]指向内存为1的地址,此时p的地址不再指向s.i的地址了。
s.p[0]=2;// *((int *)1) =2;对未定义的地址空间赋值,会出错
正确做法:对调//1和//2
即
s.p[0]=2;//2
s.p[1]=1;//1
程序不会出错,因为刚开始s.p还是指向s.i的空间,s.p[0]=2实际上是对s.i=2赋值;而s.p[1]=1,将s.p的地址空间指向内存为1 的地址。(虽然这样不大好)