美文网首页C语言&嵌入式
C语言面试题---字符串拷贝函数与内存拷贝函数

C语言面试题---字符串拷贝函数与内存拷贝函数

作者: 安想创新教育 | 来源:发表于2017-12-28 11:56 被阅读67次

    版权声明:本文转载于公众号TeachPlus---C语言面试题---字符串拷贝函数与内存拷贝函数


                    

    看看下面的这题:

    strcpy()和memcpy()的区别?

    答案:

    strcpy是字符串拷贝函数

    memspy是内存拷贝函数

    strcpy()和memcpy()都可以用来拷贝字符串,strcpy()拷贝以’\0’结束,

    但memcpy()必须指定拷贝的长度。

    本题解析

    本题的重点一个是这两个函数的使用,另一个就是关于字符串的结束标志'\0'了。

    c语言中的字符串,实际上就是一个字符数组,那么怎么把字符串字符数组区分开来,就得用到字符串的结束标志了。

    对于上面的两个问题,大家可以下面的程序作为参考:

    # include  <stdio.h>

    # include  <stdlib.h>

    # include  <string.h>

    int main()

    {

        charstr1[20] ="hello world";

        charstr2[20];

        charstr3[20];

        memset(str2,2,20);

        memset(str3,2,20);

        strcpy(str2,str1);

        memcpy(str3,str1,5);

        printf("%s\n",str2);

        printf("%s\n",str3);

        return0;

    }

    程序输出为:

    该程序首先声明了三个字符数组,并且将str1初始化为"hello world";

    然后使用memset函数,将str2和str3数组中的内容全部置为2,

    以确保内存中没有原来就存在的'\0';

    接下来使用strcpy方法将str1 中的内容拷贝到str2中

    再将str3使用memcpy直接进行内存拷贝,拷贝五个字节到str3中。

    最终输出str2和str3的内容。

    从输出的结果大家可以看到,str2的输出是正常的。

    因为strcpy在进行拷贝时,自动的将字符串的结束表示进行了拷贝,

    printf函数在输出的过程中检测到了'\0'标志则停止输出。

    而对于str3则输出了一大串乱码。这是因为 memcpy函数在进行拷贝的时候,

    只进行了制定的字节数的内存的拷贝,并没有自动添加'\0'标志,

    因此在printf函数输出时,不能够发现结束标志,

    所以一直将后面的乱码输出了出来,后面的乱码就是我们在一开始的时

    候通过memset函数设置的2了。

    相关知识点

    针对于字符串类的操作函数,可以考察的方面有很多种,大家可以参考下面的几道面试题:

    问:请找出下面代码里的问题:

    #include  <stdio.h>

    intmain(void)

    {

        charbuff[10];

        memset(buff,0,sizeof(buff));

        gets(buff);

        printf("\n The buffer entered is [%s]\n",buff);

        return0;

    }

    答:上面代码里的问题在于函数gets()的使用,这个函数从stdin接收一个字符串而不检查它所复

    制的缓存的容积,这可能会导致缓存溢出。这里推荐使用标准函数fgets()代替。

    还有一道题目非常有意思,单看题目来说,可能会被唬住

    问:下面是一个简单的密码保护功能,你能在不知道密码的情况下将其破解吗?

    # include   <stdio.h>

    int main(intargc,char*argv[])

    {

        intflag = 0;

        charpasswd[10];

        memset(passwd,0,sizeof(passwd));

        strcpy(passwd, argv[1]);

        if(0 == strcmp("LinuxGeek", passwd))

        {

            flag = 1;

        }

        if(flag)

        {

            printf("\n Password cracked \n");

        }

        else

        {

            printf("\n Incorrect passwd \n");

        }

        return0;

    }

    答:破解上述加密的关键在于利用攻破strcpy()函数的漏洞。所以用户在向“passwd”缓存输入随

    机密码的时候并没有提前检查“passwd”的容量是否足够。所以,如果用户输入一个足够造成缓

    存溢出并且重写“flag”变量默认值所存在位置的内存的长“密码”,即使这个密码无法通过验证,

    flag验证位也变成了非零,也就可以获得被保护的数据了。例如:

    $ ./psswd aaaaaaaaaaaaa

    Password cracked

    虽然上面的密码并不正确,但我们仍然可以通过缓存溢出绕开密码安全保护。

    要避免这样的问题,建议使用 strncpy()函数。

    对于字符串来说,比较重要的知识点,第一个时结尾标志'\0'的使用,第二个就是各种操作函数了

    对于操作函数来说,可能绝大部分人接触的都是下面这种函数:

    总结

    gets

    //没有边界检查,容易造成溢出

    scanf

    //不能接收带有空格的字符串

    strcpy

    //没有边界检查,容易造成溢出

    strcmp

    //没有边界检查,容易造成溢出

    strcat

    //没有边界检查,容易造成溢出

    但是以上函数都有各自的缺点,因此推荐使用以下函数进行替代:

    fgets

    strncpy

    strncmp

    strncat

    另外,最好时能够自己实现一下这些函数,这也是面试中常常会考察的一部分

    相关文章

      网友评论

        本文标题:C语言面试题---字符串拷贝函数与内存拷贝函数

        本文链接:https://www.haomeiwen.com/subject/wikdgxtx.html