(C)strcpy ,strncpy与strlcpy
1. 背景
好多人已经知道利用strncpy替代strcpy来防止缓冲区越界。
但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式。
2. strcpy
strcpy 是依据 /0 作为结束判断的,如果 to 的空间不够,则会引起 buffer overflow。
strcpy 常规的实现代码如下:
char * strcpy(char *to, const char *from)
{
char *save = to;
for (; (*to = *from) != '/0'; ++from, ++to);
return(save);
}
但通常,我们的 from 都来源于用户的输入,很可能是非常大的一个字符串,因此 strcpy 不够安全。
2. strncpy
在 ANSI C 中,strcpy 的安全版本是 strncpy
char *strncpy(char *s1, const char *s2, size_t n);
但 strncpy 其行为是很诡异的(不符合我们的通常习惯)。标准规定 n 并不是 sizeof(s1),而是要复制的 char 的个数。一个最常见的问题,就是 strncpy 并不帮你保证以'/0'
结束。
char buf[8];
strncpy( buf, "abcdefgh", 8 );
看这个程序,buf 将会被 “abcdefgh” 填满,但却没有 '/0'
结束符了。
另外,如果 s2 的内容比较少,而 n 又比较大的话,strncpy 将会把之间的空间都用 '/0'
填充。这又出现了一个效率上的问题,如下:
char buf[80];
strncpy( buf, "abcdefgh", 79 );
上面的 strncpy 会填写 79 个 char,而不仅仅是 “abcdefgh” 本身。
strncpy 的标准用法为:(手工写上 '/0'
)
strncpy(path, src, sizeof(path) - 1);
path[sizeof(path) - 1] = '/0';
len = strlen(path);
3. strlcpy
// Copy src to string dst of size siz. At most siz-1 characters
// will be copied. Always NUL terminates (unless siz == 0).
// Returns strlen(src); if retval >= siz, truncation occurred.
size_t strlcpy(char *dst, const char *src, size_t siz);
使用 strlcpy,就不需要我们去手动负责'/0'
了,仅需要把 sizeof(dst) 告之 strlcpy 即可:
strlcpy(path, src, sizeof(path));
len = strlen(path);
if ( len >= sizeof(path) )
printf("src is truncated.");
并且 strlcpy 传回的是 strlen(str),因此我们也很方便的可以判断数据是否被截断。
[* 一点点历史 *]
strlcpy 并不属于 ANSI C,至今也还不是标准。
strlcpy 来源于 OpenBSD 2.4,之后很多 unix-like 系统的 libc 中都加入了 strlcpy 函数,我个人在 FreeBSD、Linux 里面都找到了 strlcpy。(Linux使用的是 glibc,glibc里面有 strlcpy,则所有的 Linux 版本也都应该有 strlcpy)
但 Windows 下是没有 strlcpy 的,对应的是strncpy和memset函数
本篇文章来源于 Linux公社网站(www.linuxidc.com)
原文链接:http://www.linuxidc.com/Linux/2012-06/61893.htm
(C)strcpy ,strncpy与strlcpy的更多相关文章
- C语言strcpy,strncpy和strlcpy讲解
前言 C风格的字符串处理函数有很多,如strcpy().strcat()等等. strcpy与strcat char* strcpy (char* dest, const char* src); ch ...
- (C)strcpy ,strncpy和strlcpy的基本用法
好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. strcpy strcpy 是依据 /0 作为结束判断的, ...
- C语言中函数strcpy ,strncpy ,strlcpy的用法【转】
转自:http://blog.chinaunix.net/uid-20797562-id-99311.html strcpy ,strncpy ,strlcpy的用法好多人已经知道利用strncpy替 ...
- C语言中函数strcpy ,strncpy ,strlcpy的用法
strcpy ,strncpy ,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. s ...
- Linux C中strcpy , strncpy , strlcpy 的区别
strcpy ,strncpy ,strlcpy的用法 好多人已经知道利用strncpy替代strcpy来防止缓冲区越界. 但是如果还要考虑运行效率的话,也许strlcpy是一个更好的方式. 1. s ...
- strcpy、strncpy、strlcpy的区别
- C语言——常用标准输入输出函数 scanf(), printf(), gets(), puts(), getchar(), putchar(); 字符串拷贝函数 strcpy(), strncpy(), strchr(), strstr()函数用法特点
1 首先介绍几个常用到的转义符 (1) 换行符“\n”, ASCII值为10: (2) 回车符“\r”, ASCII值为13: (3) 水平制表符“\t”, ASCII值为 9 ...
- strcpy/strncpy/strcpy_s比较
转载自:http://blog.csdn.net/caomiao2006/article/details/4766416 strcpy()是依据源串的/0作为结束判断的,不检查copy先的Buffer ...
- C++ strcpy strcpy_s strncpy strlcpy
strncpy的用法:它与strcpy的不同之处就在于复制n个字符,而不是把所有字符拷贝(包括结尾'\0'). 函数原型:char * strncpy(char *dst,const char * s ...
随机推荐
- 将list分成等数量
import java.util.ArrayList; import java.util.List; public class CollectionGroupUtil { public static ...
- AtCoder Grand Contest 005F - Many Easy Problems
$n \leq 200000$的树,从树上选$k$个点的一个方案会对$Ans_k$产生大小为“最小的包括这$k$个点的连通块大小”的贡献.求每个$Ans_k$.膜924844033. 看每个点对$An ...
- hdu 4965 矩阵快速幂 矩阵相乘性质
Fast Matrix Calculation Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/131072 K (Jav ...
- 湘潭大学oj 1206 Dormitory's Elevator dp
27153 njczy2010 1206 Accepted 1976 KB 234 MS G++ 1415 B 2014-09-28 10:01:23 真是吐血ac,,,,这么easy的题..... ...
- nginx的配置文件 【nginx.conf】
#user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #erro ...
- 三种Model模式
目前项目中可能出现的三种Model模式,对于我们现在开发的一个项目,我觉得使用DDD的思想来设计模型比较清晰,使用DDD的思想把模型model分成了如下三种:ViewModel,它与页面相关,Doma ...
- 数学知识巧学JCF(Java Collections framework)
不知你是否还记得高中我们学过的集合,映射,函数,数学确实很牛逼,拿它来研究java集合类,轻而易举的就把知识理解了.本篇文章适合初学java集合类的小白,也适合补充知识漏缺的学习者,同时也是面试者可以 ...
- ubuntu下安装jdk、tomcat、mysql
1.JDK安装 方法1: 将JDK安装包解压缩之后,编辑~/.bashrc文件,在该文件里面加入下面的配置,然后通过source ~/.bashrc.JDK即安装成功. export JAVA_HOM ...
- luogu P1043 数字游戏
题目描述 丁丁最近沉迷于一个数字游戏之中.这个游戏看似简单,但丁丁在研究了许多天之后却发觉原来在简单的规则下想要赢得这个游戏并不那么容易.游戏是这样的,在你面前有一圈整数(一共n个),你要按顺序将其分 ...
- python远程访问hive
#!/usr/bin/pythonimport syssys.path.append('/home/zhoujie/Downloads/hive-0.7.0-cdh3u0/lib/py')from h ...