问题描述
- 一个动态内存分配的问题,函数执行后p指向哪里?
-
一下是我的代码:#include<stdio.h> #include<stdlib.h> #include<string.h> char *strcnp(char *sd,char *ds) { char *q=sd; while((*ds++=*sd++)!='') NULL; return q; } int main() { char *a[4]={"abc","def","whf","where"}; printf("%d,%dn",sizeof(a),sizeof(a[3])); char *p=NULL; p=(char *)malloc(strlen(a[0])+1);//若无此句,运行出现段错误 strcnp(a[0],p); //此句执行过后,p指向哪里? printf("%sn",p); free(p); return 0; }
解决方案
p根本没有变,因为你的strcnp只能修改指针指向的内容,而不能修改指针本身地址。如果你想修改p的地址,需要传递char**
解决方案二:
strcnp(a[0],p); //是函数传参,传递的是指针P存储的数值,也就是动态开辟的内存空间首地址,这样strcnp()处理的是指针P指向的内存空间。
不过函数参数传递,要么是通过寄存器,要么是通过函数堆栈,这里a[0],p是通过寄存器传参,也就是拷贝变量P的数值到寄存器,程序由主程序跳转到子函数strcnp()后,取相应寄存器数值赋值给堆栈上临时指针变量ds,指针后移的一直是堆栈上新开辟的临时变量ds,而不是P,P的数值一直未变。
解决方案三:
疑问主要在*ds++这里,ds自增不是使得ds后移么,后移之后为什么还指向分配内存的首地址呢?迷糊了
解决方案四:
以下是我更改代码做的输出:
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *strcnp(char *sd,char *ds)
{
char *q=sd;
//ds=(char *)malloc(strlen(sd)+1);
while((*ds++=*sd++)!='')
printf("while dizhi:%dn",ds);
return q;
}
int main()
{
char *a[4]={"abc","def","whf","where"};
printf("%d,%dn",sizeof(a),sizeof(a[3]));
char *p=NULL;
p=(char *)malloc(strlen(a[0])+1);//若无此句,运行出现段错误
printf("qian dizhi:%dn",p);
strcnp(a[0],p);
printf("hou dizhi:%dn",p);
printf("%sn",p);
free(p);
char *q=a[3];
printf("%sn",q);
return 0;
}
输出结果:
16,4
qian dizhi:152453128
while dizhi:152453129
while dizhi:152453130
while dizhi:152453131
hou dizhi:152453128
abc
where
可见在函数strcnp内,ds的值是改变的,但是函数strcnp执行完p的指向不变,这是为什么,传参只是一份拷贝究竟是神马依稀?
解决方案五:
可不可以这样理解:传地址调用是一种特殊的传值调用,函数形参传递的只是实参值的一份拷贝;由于实参的值是个地址,因此对形参的操作会改变实参所指向变量的值,同时也是形参所指向变量的值
时间: 2024-09-21 20:40:29