第1个回答 2019-01-24
int main(){
//在栈内存上,int类型,占sizeof(int)=4字节
int a;
//在栈内存上,double类型,占sizeof(double)=8字节
double b;
//指针变量p在栈内存上,占sizeof(double*)字节,32位程序是4,64位程序是8
//p本身是一个变量,指针类型的变量,其值是一个整数,是用来存放虚拟地址的。
double *p; //没有初始化
//sizeof操作符是针对类型求占用字节数,因p是double *类型,
//所以*p是double类型,sizeof(*p)实际上是sizeof(double)=8
printf("%d",sizeof(*p)); //8
*p = 5; //运行时错误,p没有指向一个合法的地址空间,非法操作。
p = &b; //正确,p指向栈内存上的b变量
*p = 5; //正确,p指向b,此句执行后b的值也是5
printf("%lf,lf",*p,b); // 5.0,5.0
//修改p的指向,malloc在堆内存上申请了8字节,并把首地址赋给了q,
//即p指向malloc从堆内存申请来的8字节,不再指向b
p = (double*)malloc(sizeof(double));
*p = 10; //正确
printf("%lf,lf",*p,b); // 10.0,5.0
//释放p指向的堆内存8字节
free(p);
//运行时错误,p为野指针,没有指一个向合法地址,非法操作
*p = 10;
//正确,p指向虚拟地址0,也是空指针
p = 0;
//运行时错误,不能对0地址上的字节赋值。
*p = 10;
//正确,p指向虚拟地址100
p = 100;
//可能运行时错误,没法保证此时虚拟地址100一定存在,内存访问违规
*p = 10;
printf("%d",p); // 正确,100
//综上,关键是理解并区分指针变量本身和它指向的地址上的数据。
}