C语言面试题---指针篇(二)

版本声明:本文转载于公众号TeachPlus

C语言面试题---指针篇(二)

在上一篇中,我们介绍了关于内存分区的划分,那么现在我们就来看一道跟这个相关的面试题:

阅读下面的程序,找出其中的错误,并说明原因。
# include <stdio.h>
int  main()
{
    char *str = "abcd";
    str[2] = "f";
    printf("%s\n",str);
    return 0;
}

本题解析

答案:该程序会段错误,因为程序中仅仅只定义了一个字符指针,并没有定义字符串,
只是将字符指针指向了“abcd”这个字符串常量了,而字符串常量"abcd"的存储位置是在
内存的数据段(或静态存储区)中的,存储在这个位置的值,是不允许修改的,
因此在程序中使用 str[2] ='f'  试图修改字符串常量的值,就会出现段错误,当然,
我们可能等不到段错误的出现,因为程序在编译阶段就会被报警告了。

相关知识点

静态存储区的作用非常重要,但是对于我们而言最重要的还是栈区和堆区。对于堆区而言,
重要的就是malloc函数和free函数,一起来看一道关于堆区的题目:
阅读下面程序,写出程序的运行结果:
# include <stdio.h>
# include <stdlib.h>
# include <string.h>

void  getMemory( char **p ,  int num)
{
    *p = malloc(num);
}
   int  main()
  {
      char * str = NULL;
      getMemory(&str,100);
      strcpy(str,"hello");
      free(str);
      if(str != NULL)
      {
          printf("%p\n",str);
      }
      return 0;
}
程序运行的结果输出的是指针对象str的值。
在给指针分配内存的时候,其实给指针对象赋了了一个值,这个值就是这片空间的首地址。
随后进行了free操作,free 只是释放的str指向的内存空间,它本身的值还是存在的.
因为内存空间已经被释放了,所以这个指针对象的值,其实是指向没有被分配空间的地址,
如果输出语句之前还存在分配空间的操作的话,这段存储空间是可能被重新分配给其他变量的,

访问这样的越界空间,编译是没有问题的,但是运行时会出现“Segmentation fault”.

所以free之后,有一个好的习惯就是将str=NULL.

不过在该程序中,如果输出str的值,通常还是会打印出hello来。

这是因为,进程中的内存管理理一般不是由操作系统完成的,而是由库函数自己完成的。

当你malloc一块内存的时候,管理库向操作系统申请一块空间(可能会比你申请的大一些),
然后在这块空间中记录一些管理信息(一般是在你申请的内存 前面一点),并将可用
内存的地址返回。但是释放内存的时候,管理库通常都不会将内存还给操作系统,
也可以理解成为不会立即清除内存空间中的内容的,因此你是可以继续访问这块地址的。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值