今天到I 公司去面试,面试方式比较特殊,没有笔试,就是2 个面试官,一人一句轮番发问,涉及面很广,涉及到操作系统(MMU 、page out 、process/thread 、semaphore 、interrupt), OOP( 多态、design pattern) 、数据结构( 排序、二叉查找树) 、计算机网络(OSI 5 层) 、C 语言(big/small endian) 、英语口语等等,问了大约一个小时左右。
所有问题都是口头表述,只在纸上写了一个memcpy 程序,用C 语言实现,脑子一发蒙,既然写成了strcpy ,真该死。
回家了查询了一下memcpy 定义,如下:
Void *memcpy(void *dest, const void *src, unsigned int count);
查询msdn, 发现Remark 如下:
memcpy copies count bytes from src to dest ; If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions.
以上描述针对dest 和 src 所指的内存地址有重叠的情况,内存地址重叠情况,memcpy 函数处理步骤未定,而memmove 对重叠情况给予处理;
在winXP+visual c++2005 测试 memcpy 函数,程序如下:
#include "stdafx.h"
#include
int _tmain (int argc , _TCHAR * argv [])
{
char s [16] = "aabbcc" ;
char d [16] = {0};
memcpy (s +2, s , 4);
printf ("%s" , s );
return 0;
}
结果输出 “aaaabb”, 由此可见windows 平台的c 运行时MSVCRT 的memcpy 函数对重叠部分做了处理,同memmove 的实现。//notes: 如果重叠部分不做处理,应该输出”aaaaaa”
下面我们用c 语言来实现memcpy 函数, 首先我们写出不对内存重叠的处理函数,如下:
void *memcpy_no_handle_overlap (void *dest , void *src , unsigned int count )
{
if ((NULL ==dest ) || (NULL ==src ))
return NULL ;
char *d = (char *)dest ;
char *s = (char *)src ;
//Do normal (Upwards) Copy
while (count -- > 0)
*d ++ = *s ++;
return dest ;
}
测试程序如下:
int _tmain(int argc, _TCHAR* argv[])
{
char s[16] = "aabbcc";
char d[16] = {0};
memcpy_no_handle_overlap(s+2, s, 4);
printf("%s", s);
return 0;
}
输出结果”aaaaaa”
下面讨论处理memory overlapping 情况,如下图:
判断overlapping 条件如下:
If ( (dest <= src) || // green region 1
(dest >=src+count) ) // green region 2
{
// no memory overlapping
}
Else // red region 3
{
// there is overlapping
}
Overlapping 的处理:
我们可以看到memcpy_no_handle_overlap 函数,是从低地址依次赋值到高地址;在处理overlapping 时,如果我们采用同样的方法( 低地址到高地址) ,高地址的值将会被覆盖,所以我们应该从高地址依次到低地址赋值,如下图:
函数代码如下:
void *memcpy_handle_overlap(void *dest, void *src, unsigned int count)
{
if ((NULL==dest) || (NULL==src))
return NULL;
char *d = (char *)dest;
char *s = (char *)src;
//Check for overlapping buffers:
if ( (d<=s) || (d>=s+count) )
{
//Do normal (Upwards) Copy
while (count-- > 0)
*d++ = *s++;
}
else
{
//Do Downwards Copy to avoid propagation
while (count > 0)
{
*(d+count-1) = *(s+count-1);
--count;
}
}
return dest;
}
测试代码:
int _tmain(int argc, _TCHAR* argv[])
{
char s[16] = "aabbcc";
char d[16] = {0};
memcpy_handle_overlap(s+2, s, 4);
printf("%s", s);
return 0;
}
输出结果为: “aaaabb “
最后测试代码如下:
int _tmain(int argc, _TCHAR* argv[])
{
char s[16] = "aabbcc";
memcpy_no_handle_overlap(s+2, s, 4);
printf("memcpy(ignore memory overlapping): %s/n", s);
strcpy(s, "aabbcc");
memcpy_handle_overlap(s+2, s, 4);
printf("memcpy(handle memory overlapping): %s/n", s);
strcpy(s, "aabbcc");
memcpy(s+2, s, 4);
printf("memcpy( MSVCRT ): %s/n", s);
strcpy(s, "aabbcc");
memmove(s+2, s, 4);
printf("memmove( MSVCRT): %s/n", s);
return 0;
}
输出结果为:
memcpy(ignore memory overlapping): aaaaaa
memcpy(handle memory overlapping): aaaabb
memcpy( MSVCRT ): aaaabb
memmove( MSVCRT): aaaabb
char* Reverse(char* s) {//将q指向字符串最后一个字符char* q = s ;while( *q++ ) ;q -= 2 ; //分配空间,存储逆序后的字符串。char* p = newchar[sizeof(char) * (q - s + 2)] ; char* r = p ;// 逆序存储whil...
二级指针相对于一级指针,显得更难,难在于指针和数组的混合,定义不同类型的二级指针,在使用的时候有着很大的区别 第一种内存模型char *arr[] 若有如下定义 char *arr[] = {"abc", "def", "ghi"}; 这种模型为二级指针的第一种内存模型,在理解的时候应该这样理解:定义了一个指针数组(char *...
今天在弄一下啊小小程序的时候。报错,出现了问题。先看代码 int main(int argc, char* argv[]) {char *filename = "interface_ipset_1_1.json";char* split1 = "_";char* split2 = ".";char splitfile1[4][...
wchar_t*,wchar_t,wchat_t数组,char,char*,char数组,std::string,std::wstring,CString....#include
问题的提出:设计一个用于管理朋友信息的程序。将朋友信息(年龄、姓名、电话)存放在MyFrd.dat中,从文件读出这些信息并显示,并能按姓名(要求可简化输入,如只输入姓氏便可查询)进行查询,将查询信息输出屏幕。 1 #include
以strncpy为例: char dest[4] = {""}; char src[] = {"123456789"}; strncpy(dest, src, 3); puts(dest); 输出结果为 123 看到了吗,strcpy函数中的参数是字符串数组的名字,而数组名本质上是指针,那么,src+3 就可以实现将 src中...