当strncpy遇上指针

随着对代码安全性的要求越来越高,strncpy正式登上了历史舞台。

strncpy在项目中使用较多,一不注意可能会出错,因此记录一下,方便后续翻阅查看。

strncpy函数原型

    char * strncpy(char * str2, char * str1, int size);

基本用法

    char src[20] = {0};
    strncpy(src, "This is test string", sizeof(src)-1);
    printf("src[%s]\n", src);

打印结果为:

    src[This is test ]

遇到指针之后

    char src[20] = {0};
    strncpy(src, "This is test string", sizeof(src)-1);

    char* dst = (char*)malloc(20);
    strncpy(dst, src, sizeof(dst)-1);
    printf("src[%s],len[%d]\ndst[%s],len[%d]\n", src, strlen(src), dst, strlen(dst));

运行结果如下:

    src[This is test ],len[19]
    dst[Thi],len[3]

我们发现运行结果出现了异常。原因的sizeof计算指针变量的大小时,并不是返回指针所指向的空间的大小,而是指针变量本身的大小,在32位系统中为4字节,因此,目标字符串长度为3,被无意间截断了。

为了避免这种情况,我们常使用如下方式调用strncpy:

    char src[20] = {0};
    strncpy(src, "This is test string", sizeof(src)-1);

    char* dst = (char*)malloc(20);
    strncpy(dst, src, strlen(src)+1);
    printf("src[%s],len[%d]\ndst[%s],len[%d]\n", src, strlen(src), dst, strlen(dst));

此时,结果就正常了。

注意,此时使用的是strlen(src)+1,而不是strlen(dst)-1。

总结

  • 安全拷贝字符串,使用strncpy函数
  • 注意拷贝字符串的长度计算,字符数组可使用sizeof计算,字符指针需要使用原字符串长度(strlen(src)+1),+1是因为当拷贝的长度size大于待拷贝字符串长度时,strncpy函数会在后面自动补上'\0'。我们多拷贝一个字符,相当于让strncpy函数帮忙在目标字符串结尾加上'\0'结束符。
  • sizeof计算指针变量长度,是int类型在该系统所占内存的大小

你可能感兴趣的:(当strncpy遇上指针)