指针是能够存放一个地址的一组存储单元。既然是存储单元,指针当然也有地址和值这两个属性,所以和普通变量一样也存在副本的概念。
看一段代码:
#stdio.h stdlib.h string.h
void GetMemory(char *p, int num);
int main(void){
char *str = NULL;
GetMemory(str,100);
strcpy(str,”This is the message!\n”); //此处会产生 segmengtation fault
printf(str);
return 0;
}
void GetMemory(char *p, int num)
{
p = (char *)malloc(sizeof(char)*num);
}
程序的目的是利用GetMemory 给str动态分配内存,继而strcpy给str赋值。实际执行情况是,GetMemory 创造了str的副本p,并给p分配了内存(内存泄露)。str的数值依然为NULL,继而在调用用strcpy给str赋值时产生段错误。
正确的代码:
#stdio.h stdlib.h string.h
void GetMemory(char **p, int num)
int main(void){
char *str = NULL;
GetMemory(&str,100);
strcpy(str,”This is the message!\n”); /
printf(str);
return 0;
}
void GetMemory(char **p, int num)
{
*p = (char *)malloc(sizeof(char)*num);
}
GetMemory 创造了str地址的副本p,并利用*p修改了str的内容,达到了动态申请内存的目的。
补充例子:
#define ADD(p) {p++;(*p)++;}
Add(int *p) {p++;(*p)++;}
int a[]={0,1,2};
int main()
{
int *p=a;
ADD(p)
ADD(p)
printf(”%d,%d,%d\n”,a[0],a[1],a[2]);
//a[0]=0 a[1]=2 a[2]=3
p=a;
Add(p);
Add(p);
printf(”%d,%d,%d\n”,a[0],a[1],a[2]);
}