[经典面试题]实现memcpy库函数

标签: 面试题 memcpy
2907人阅读 评论(1) 收藏 举报
分类:

【题目】

已知memcpy的函数为: void* memcpy(void *dst , const void* src , size_t count)

其中dst是目的指针,src是源指针。不调用c++/c的memcpy库函数,请编写memcpy。


-------百度,网新恒天校园招聘

【解析】

1 按照ANSI(American National Standards Institute)标准,不能对void指针进行算法操作,

即不能对void指针进行如p++的操作,所以需要转换为具体的类型指针来操作,例如char *

2 memcpy是对内存进行操作,可能遇到内存重叠的情况,同样的问题存在于memmove中, 但是源代码中这两个函数的处理方式不一样:

memcpy中dst和src中的区域不能重叠,否则会出现未知结果。函数没做任何内存的处理,内存是否重叠由程序员自己控制。

memmove里面则判断了内存重叠的情况,当内存重叠时从后往前复制,以确保复制正常处理。

【代码】

#include <iostream>
using namespace std;

//实现memcpy库函数
void* memcpy(void *dst, const void *src, size_t count){
    // 容错处理
    if(dst == NULL || src == NULL){
        return NULL;
    }
    unsigned char *pdst = (unsigned char *)dst;
    const unsigned char *psrc = (const unsigned char *)src;
    //判断内存是否重叠
    bool flag1 = (pdst >= psrc && pdst < psrc + count);
    bool flag2 = (psrc >= pdst && psrc < pdst + count);
    if(flag1 || flag2){
        cout<<"内存重叠"<<endl;
        return NULL;
    }
    // 拷贝
    while(count--){
        *pdst = *psrc;
        pdst++;
        psrc++;
    }
    return dst;
}

int main(){
    char c1[] = "hello world";
    memcpy(c1+3, c1, 9);
    cout<<"memcpy result:"<<c1<<endl;
    char c2[] = "love you";
    memcpy(c1,c2,8);
    cout<<"memcpy result:"<<c1<<endl;
}


#include <iostream>
#include <string.h>
using namespace std;

//实现memmove库函数
void* memmove(void *dst, const void *src, size_t count){
    // 容错处理
    if(dst == NULL || src == NULL){
        return NULL;
    }
    unsigned char *pdst = (unsigned char *)dst;
    const unsigned char *psrc = (const unsigned char *)src;
    //判断内存是否重叠
    bool flag1 = (pdst >= psrc && pdst < psrc + count);
    bool flag2 = (psrc >= pdst && psrc < pdst + count);
    if(flag1 || flag2){
        // 倒序拷贝
        while(count){
            *(pdst+count-1) = *(psrc+count-1);
            count--;
        }//while
    }
    else{
        // 拷贝
        while(count--){
            *pdst = *psrc;
            pdst++;
            psrc++;
        }//while
    }
    return dst;
}

int main(){
    // 内存重叠
    char c1[] = "hello world";
    memmove(c1+3, c1, 8);
    cout<<"memmove result:"<<c1<<endl;
    // 内存不重叠
    char c2[] = "hello world";
    char c3[] = "love you";
    memmove(c2,c3,8);
    cout<<"memmove result:"<<c2<<endl;
}


#include <iostream>
using namespace std;

void* memmove(void* str1,const void* str2,size_t n){
    char* pStr1= (char*) str1;
    const char* pStr2=(const char*)str2;
    // 正序拷贝
    if  (pStr1  < pStr2) {
        for(size_t i=0;i!=n;++i){
            *(pStr1++)=*(pStr2++);
        }
    }
    // 倒序拷贝
    else{
        pStr1+=n-1;
        pStr2+=n-1;
        for(size_t i=0;i!=n;++i){
            *(pStr1--)=*(pStr2--);
        }
    }
    return pStr1;
}


int main(){
    char str[] = "hello world";
    memmove(str+4,str,7);
    cout<<str<<endl;
    return 0;
}




查看评论

c语言中的memcpy实现

本文通过汇总一些网上搜集到的资料,总结c语言中的memcpy实现 背景 想必大多数人在面试时被要求写 memcpy的实现,很不幸,我也吃过这个亏(这种题要是写的一塌糊涂后面完全没戏),所以还是得提前准...
  • goodwillyang
  • goodwillyang
  • 2015-05-07 13:39:27
  • 15193

memcpy函数实现及其优化

1:函数原型void * memcpy ( void * destination, const void * source, size_t num ); 函数作用 参考:http://www.cp...
  • xiaobo620
  • xiaobo620
  • 2012-04-23 13:34:23
  • 29115

memcpy的函数内部实现

memcpy和memmove函数的实现,需要注意memmove的覆盖问题,还有指针类型需要考虑。下面的例子中,先给出了错误的例子,而后给出了正确的例子,引以为戒! 区别:两个函数都是进行n字节内存内...
  • limpidfabulous
  • limpidfabulous
  • 2011-10-23 23:09:54
  • 26007

strcpy函数的实现

大家一般认为名不见经传strcpy函数实现不是很难,流行的strcpy函数写法是: char *my_strcpy(char *dst,const char *src) { assert(ds...
  • Gpengtao
  • Gpengtao
  • 2012-04-15 23:23:32
  • 87548

memcpy函数详解

函数原型:void *memcpy(void*dest, const void *src, size_t n); 用法:#include 功能:从源src所指的内存地址的起始位置开始,拷贝n个字节的数...
  • xiaominkong123
  • xiaominkong123
  • 2016-06-22 14:17:54
  • 16024

关于C函数memcpy的实现细节思考

前段时间和朋友讨论关于C基础函数memcpy的实现细节时,收货颇多。这个函数在C / C++编程领域中使用率是比较高的(可能排在前10左右)。但鲜有人去研究其实现原理。为了弄清楚其实现,我给自己出了一...
  • u012935160
  • u012935160
  • 2014-04-15 18:03:10
  • 2481

C语言之memcpy函数

【FROM MSDN && 百科】 原型:  void *memcpy(void *dest, const void *src, size_t n); #include 功能:从源s...
  • hgj125073
  • hgj125073
  • 2013-01-05 12:10:37
  • 34895

memcpy源码

一直以来知道memcpy函数有问题,没有处理内存重叠的情况;而memmove函数对这种情况进行了处理。今天碰巧有同事问到,特地翻了一下源码,了解一下实现方法,大体如下: void *memcpy...
  • lxgwm2008
  • lxgwm2008
  • 2013-09-23 22:05:32
  • 7772

【面试题,纸上写程序】实现memcpy函数

[以下内容转自:http://my.oschina.net/renhc/blog/36345,作者:任洪彩,2011-12-02],这篇解释的相对比较透彻些! 面试中如问到memcpy的实现,那就要...
  • wojiushiwo987
  • wojiushiwo987
  • 2012-09-26 12:32:26
  • 11561

【C语言】memcpy函数的实现

1函数原型 void *memcpy(void *dest, const void *src, size_t n); 2功能 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指...
  • liuxiaoqian_
  • liuxiaoqian_
  • 2015-05-21 23:27:49
  • 1136
    个人资料
    专栏达人 持之以恒
    等级:
    访问量: 159万+
    积分: 2万+
    排名: 371
    博客专栏
    最新评论