C语言编译器(C语言编程软件)完全攻略(第二十七部分:VS安全函数问题(C语言安全函数)是怎么回事?如何解决?)

介绍常用C语言编译器的安装、配置和使用。

二十七、VS安全函数问题(C语言安全函数)是怎么回事?如何解决?

在 VS(Visual Studio)下编译C语言程序,如果使用了 scanf()、gets()、strcpy()、strcat() 等与字符串读取或操作有关的函数,有时候VS会报错,提示该函数可能不安全,并且建议替换为带有_s后缀的安全函数,如下图所示:

1、什么是安全函数(safe function)

scanf()、gets()、strcpy()、strcat() 等都是C语言自带的函数,它们都是标准函数,但是它们都有一个缺陷,就是不安全,可能会导致数组溢出或者缓冲区溢出,让黑客有可乘之机,从而发起"缓冲区溢出"攻击。

scanf_s()、gets_s()、strcpy_s()、strcat_s() 是 C11 标准新引入的安全函数,它们在读取或操作字符串时要求指明长度, 这样一来,过多的字符就会被过滤掉,避免了数组或者缓冲区溢出。

下面我们以 scanf_s() 为例来讲解。

scanf() 在读取字符串时不会检查字符个数,它不知道数组或缓冲区到底能容纳多少个字符,例如:

char buf5={0};

scanf("%s", buf);

当用户输入abcdeABCDE 这10个字符时,scanf() 会全部读取,并放入 buf 中,不过 buf 最多只能存储 5 个字符,不足以容纳用户输入的全部数据,所以多出来的 5 个字符就会使用 buf 后面的内存,而 buf 后面的内存可能没有使用权限,或者已经被别的数据占用,这就导致程序在运行时可能会出现不可预知的错误。

最要命的是,这种错误只能等到程序运行时才能检测出来,在编译期间根本无法检测;一旦检测出来只有一种后果,就是程序被操作系统终止,也就是我们常说的"程序崩溃"。

更改上面的代码,使用 scanf_s() 代替 scanf():

char buf5 = {0};

scanf_s("%s", buf, 5);

scanf_s() 最后一个参数用来指明数组或者缓冲区的大小,假设它的值为 n,那么最多只允许读取 n-1 个字符(因为最后要存储'\0' ),多出来的字符就不再读取了,这样就可以避免读入过多的字符。与 scanf() 相比,scanf_s() 显然更加安全。

但是,安全函数不但使用麻烦,而且也不是所有的编译器都支持,也不被绝大多数教程采用,不利于大家学习。

2、如何取消安全函数的限制

我们通过对 VS 做适当的设置,让它不再强制使用安全函数,从而可以使用 scanf()、gets()、fgets()、strcpy()、strcat() 等C语言的标准函数去编程。

VS 之所以会提示使用安全函数,是因为它进行了SDL检查(安全性开发生命周期检查),只要将它取消就可以了。

  1. 菜单栏中选择 "项目 --> xxx属性"(xxx为创建的项目名称),或者直接按下组合键"Alt+F7",如下图所示:
  1. 此时会弹出如下图所示的一个对话框,选择"C/C++ --> SDL检查",将"是"改为"否",如下图所示:

3)最后点击"确定"按钮,重新运行程序,你会发现程序可以正常运行了。

另外,VS2010、VS2015 等低版本的 VS 可以在创建项目之处就取消 SDL 检查(如下图所示),但是到了 VS2017 时就不行了,创建项目时没有这个选项了,只能在创建项目完成以后再按照以上步骤取消 SDL 检查。

相关推荐
BreezeJuvenile几秒前
基于C语言的SPSC环形缓冲区程序实现
c语言·环形缓冲区
SuperByteMaster18 分钟前
recursive mutex的使用场景和场景代码
c语言
程序猿阿森21 分钟前
Python 闭包与装饰器:从入门到精通
开发语言·python·面试
余额瞒着我当琳35 分钟前
C++--vector底层,leetcode118杨辉三角实战,对于传统reserve的坑点,迭代器失效
开发语言·c++
曹牧38 分钟前
C#:字符串做20位截断
开发语言·c#
醉城夜风~1 小时前
(超详细)C++多态(Polymorphism)
开发语言·c++
这是个栗子1 小时前
【JS代码分析】前端鉴权基础:Token 的本地存储与状态重置实践
开发语言·前端·javascript
wuyk5551 小时前
7.AVL 树:第一个自平衡二叉搜索树
开发语言·stm32·单片机·算法
SomeB1oody1 小时前
【RustyML入门】5.3. 聚类指标
开发语言·后端·机器学习·rust·教程
OPEN-F1 小时前
Python进阶教程:Web开发入门(Flask)
开发语言·python