转自:http://blog.csdn.net/edwardlulinux/article/details/47134513

版权声明:本文为博主原创文章,未经博主允许不得转载。

首先来看一个司空见惯的c语言列子:
#include <stdio.h>
#include <string.h>

int main()
{
    unsigned char arry[] = {0x00,0x01,0x02,0x03};
    unsigned char dest[] = {0xff,0xff,0xff,0xff};

strncpy(dest,arry,sizeof(arry));

printf("dest[0] is %X\n",dest[0]);
    printf("dest[1] is %X\n",dest[1]);
    printf("dest[2] is %X\n",dest[2]);
    printf("dest[3] is %X\n",dest[3]);

return 0;
}

运行后发现了:
dest[0] is 0
dest[1] is 0
dest[2] is 0
dest[3] is 0
原来的数组中的数据怎么没有了?

傻眼了吧,就是这个问题困扰了我一个下午。不过最后感觉不对,可以用memcpy来完事。随后用memcpy代替,果然问题没有再出现。原来的数组中的数据依次被赋值为新的源地址数值。
百思不得其解,回家后打开电脑查看了一下strncpy原代码。发现了问题:

char* strncpy(char *dest, const char *src, size_t n)
{
    size_t i;

//Note 1:
    for (i = 0 ; i < n && src[i] != '\0' ; i++)
        dest[i] = src[i];
    //Note 2:
    for ( ; i < n ; i++)
        dest[i] = '\0';

return dest;
}

Note 1:
假设我们的源目的地址第一个字符为NULL (\0),那么第一个for循环立即返回。但是这个时候i取值为0。
Note 2:
随即进入第二个for循环,别忘了,i=0。那么在第二个for循环中巴dest第dest[1]个开始以后所有的数据都赋值为\0。

第二个for循环的本意是(当拷贝大小size n大于源字符串长度时候)把前面若干个字符拷贝后剩下的最后所有的字符格式化为\0。

原来是这样,好久没有用libc和string类的库函数了。突然这么一次还真是冷不丁的卡壳了。

记录下来,也算是为工作和学习做一次笔记。

strncpy 引起的思考,重新认识了strncpy这个函数【转】的更多相关文章

  1. 像计算机科学家一样思考python-第3章 函数

    在程序设计中,函数是指用于进行某种计算的一系列语句的有名称的组合.定义一个函数时,需要指定函数的名称并写下一系列程序语句.之后,就可以使用名称来“调用”这个函数 3.1函数调用 一个函数调用的例子 & ...

  2. [skill] strncpy里边有两个坑

    以前的笔记,今日翻出了复看了一下,转过来. ------------------------------------ 今天发现xxxdump中使用xxx_strncpy 替换 strncpy导致的bu ...

  3. 写高并发程序时慎用strncpy和sprintf

    分享一下最近做程序优化的一点小心得:在写高并发交易代码时要谨慎使用strncpy和sprintf. 下面详细介绍一下这样说的原因及建议实践: 1 慎用strncpy因为它的副作用极大 我们平时使用st ...

  4. 为什么用strlcpy取代strncpy

    为什么用strlcpy取代strncpy 标签: C, C语言, strlcpy, strncpy 标题: 为什么用strlcpy取代strncpy作者: Demon链接: http://demon. ...

  5. strcpy/strncpy/strcpy_s比较

    转载自:http://blog.csdn.net/caomiao2006/article/details/4766416 strcpy()是依据源串的/0作为结束判断的,不检查copy先的Buffer ...

  6. LoadRunner事务/集合点/思考时间详解(转)

    在LoadRunner的脚步编写中,有三个重要的概念:事务.集合点.思考时间. 一.事务: 事务又称为Transaction,我们为了衡量某个action的性能,需要在action的开始和结束位置插入 ...

  7. 关于C++函数思考1(缺省的六大函数)

    我们知道大神们在设计C++时候就给C++有六个默认的函数,所谓默认就是,无需我们这些程序猿们动手去写,仅仅要你在将类实例化.即创建一个对象,在利用对象进行数据操作时候,就会编译器自己主动调用默认的函数 ...

  8. loadrunner 事务、同步点和思考时间

    事务 在LoadRunner里,我们定义事务主要是为了度量服务器的性能.每个事务度量服务器响应指定的Vuser请求所有的时间,这些请求可以是简单任务,也可以是复杂任务. 要度量事务,需要插入Vuser ...

  9. LoadRunner几个重要的概念:事务、集合点、思考时间

    在LoadRunner的脚步编写中,有三个重要的概念:事务.集合点.思考时间 事务: 事务又称为Transaction,在LoadRunner中的定义如下:An end-to-end(browser- ...

随机推荐

  1. Kubernetes实战 高可用集群搭建,配置,运维与应用

    1-1 K8S导学 1-2 搭建K8S集群步骤和要点介绍 1-3 搭建三节点Ubuntu环境 1-4 安装容器引擎 1-5 下载Kubeadm.node组件和命令行工具 1-6 向集群中加入worke ...

  2. eclipse返回快捷键

    1.图上第一个箭头(Ctrl + Q) 返回上一个编辑点(编辑,修改代码) 2.图上第二个箭头(Alt + Left) 返回上一个操作点(点击进入方法等操作) 3.图上第三个箭头(Alt + Righ ...

  3. 【转】C++操作符的优先级 及其记忆方法

    优先级 操作符 描述 例子 结合性 1 ()[]->.::++-- 调节优先级的括号操作符数组下标访问操作符通过指向对象的指针访问成员的操作符通过对象本身访问成员的操作符作用域操作符后置自增操作 ...

  4. Activiti工作流(二)——入门Demo及数据库

    上篇博客简单介绍了Activiti流程图的使用,这篇博客我们就根据这个流程图来完成这一个流程.  下图是Activiti的系统服务结构图,在后面的流程中,我们会用到其中的功能组件,如Repositor ...

  5. tomcat 启动报错 解决办法 A child container failed during

    控制台报错: Caused by: org.apache.catalina.LifecycleException: A child container failed during start at o ...

  6. 写一篇Hook Driver.

    关于Hook,有一本书讲的比较清楚,最近刚刚看完,<Rootkits: Subverting the Windows Kernel> http://www.amazon.com/Rootk ...

  7. 创建一个doc对象时候 如果读取了一个已存在的xml对象时候 该xml对象的结构已存在doc中 当改变该doc结构时候 不需要创建新的doc对象

    创建一个doc对象时候 如果读取了一个已存在的xml对象时候 该xml对象的结构已存在doc中 当改变该doc结构时候不 需要创建新的doc对象 直接添加即可 他会同步过去

  8. 皮肤包项目的 Gradle 脚本演化

    我在做的一个项目需要有换肤功能,换肤的方案是采用第三方库 ThemeSkinning 的实现(在其基础上修复若干 bug).皮肤的制作是把相关的资源放在一个 app module 中打包成 apk,当 ...

  9. ZOJ 3229 Shoot the Bullet | 有源汇可行流

    题目: 射命丸文要给幻想乡的居民照相,共照n天m个人,每天射命丸文照相数不多于d个,且一个人n天一共被拍的照片不能少于g个,且每天可照的人有限制,且这些人今天照的相片必须在[l,r]以内,求是否有可行 ...

  10. [Leetcode] Linked list cycle 判断链表是否有环

    Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ext ...