深拷贝和浅拷贝

#include<stdio.h>

#include<string.h>
#include<stdlib.h>
#include<vld.h>  //测试内存泄漏
int main()
{
 char buf[100]; //从键盘读取字符串
 char *arr[3]; //存放指针的数组,指向地址
 int i;
 /* 浅拷贝:多个指针指向同一段内存
 // 字符串常量属于浅拷贝,所以不能被修改
 for(i=0;i<3;i++)
 {
  scanf("%s",buf);  
  arr[i]=buf;
 }
 for(i=0;i<3;i++)
 {
  printf("%s\n",arr[i]);
 }
 */
测试:
输入:
aaa
bbb
ccc
输出:
ccc
ccc
ccc
想要输出的是aaa bbb ccc,但是实际输出的却是 ccc ccc ccc,就是因为浅拷贝的问题,arr是一个指针数组,存放的是buf的地址,buf的地址是恒定的,假设是1000,那循环三次都是1000,但是里面的内容发生了改变,原来是aaa,但是再输入bbb的时候,就覆盖了aaa,同样ccc也覆盖了bbb,所以最后buf里面存放的只有ccc,而arr是buf的地址1000,所以每次存进去的都是1000,输出数组的时候,就全是ccc了。这就是浅拷贝,实质就是多个指针指向同一段内存。

scanf从输入留缓冲区读取数值,如果输入缓冲区有数,它就可以用,没有数值或者数值不足,就要等待。缓冲区的数是从键盘缓冲区里来的。键盘缓冲区的数据只有遇到回车才送入输入流缓冲区,否则留在键盘缓冲区,不会到输入流缓冲区。所以scanf并不是一定要等回车,scanf只是等输入流缓冲区有数取,键盘一次输入很多数,回车,输入流缓冲区就有很多数了。scanf读数以空白为数的分隔符,空格,回车属于空白,回车对于scanf来说,只是数的分隔符而已。

//深拷贝:每个指针指向单独的内存
如果想要把输入的值都输出来怎么办,首先就是要创建一个和输入字符相等长度的数组保存这个字符串,再将键盘读取的数据拷贝到新的数组中去,然后数组arr的值保存新数组的地址,就可以对它们分别进行访问了。这就是深拷贝,每个指针指向单独的内存。

 for(i=0;i<3;i++)
 {
  scanf("%s",buf);
  //1.计算字符串长度
  //2.动态创建内存
     arr[i]=(char *)malloc(sizeof(char)*(strlen(buf)+1));
  //3.拷贝数据
  strcpy(arr[i],buf);

  /* 也可以这样写
  char *p=(char *)malloc(sizeof(char)*(strlen(buf)+1));
  strcpy(p,buf);
  arr[i]=p;
  */
  
 }
 for(i=0;i<3;i++)
 {
  printf("%s\n",arr[i]);
 }
 for(i=0;i<3;i++)
 {
  free(arr[i]);  //每个都要销毁
  arr[i]=NULL; //防止野指针
 }
 return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值