Re: [问题] 用memcpy 会有残余值怎么办?

楼主: overhead (overhead)   2016-02-04 00:20:57
我没有仔细看你的本文,不过针对你补充的部分:
Ptr->ListString = (char *)malloc ((Length + 1) * sizeof(char));
memset (Ptr->ListString, '\0', Length + 1);
memcpy (Ptr->ListString, CharPtr, Length);
strcat (Ptr->ListString , "\0");
printf ("%s", Ptr->ListString);
printf (" %d\n",Length);
有些建议
1. strxxx系列function以及%s顾名思义都是在处理string
string的定义就是结尾为0(='\0')的char array
因此你没有放'\0'在结尾之前,都别用这些functions,会坏掉
(这也是为啥有strxxx_s系列的理由)
2. memxxx系列的效率比strxxx系列高很多
因为后者除了要处理array以外,还要随时注意'\0'到了没
3. 虽然memxxx比较快,但copy本质上就是比用指标重复利用一块data来得慢
所以尽量用指标处理资料传递,当然用指标比较难而且比较多限制就是
4. 如果你打定主意这个array都要用string形式处理,那memset就不用做了
浪费成本
举个例子: a[0]='A', a[1]='B', a[2]='\0', a[3]='C'
b[0]='A', b[1]='B', b[2]='\0', b[3]='\0'
用printf("%s %s", a, b)印出来的a,b字串是一模一样的,都是AB
不管a[3]是多少,从s[0]开始扫到a[2]发现有'\0'时,电脑就会结束扫下去了
5. 承第一点,strcat的意思是"在str开始第一个出现'\0'的位置后面接上指定字串"
言下之意是,如果你能接上指定字串"\0",代表它前面有个'\0'
另外"\0"是个字串,里面有\跟0,用单引号包起来的'\0'才是0的意思
你strcat (Ptr->ListString , "\0");这一行是一点意义也没有的
真正帮你补0的是你一开始的memset (Ptr->ListString, '\0', Length + 1);
可如同我第四点所说的,你这样做是有点浪费成本的
因为[0]~[Length]才改完的值随即会被memcpy盖过,很心酸~
(也是可以写啦,看风格,有人觉得浪费点成本但是初始时写memset比较整齐)
建议如下:
Ptr->ListString = (char *)malloc ((Length + 1) * sizeof(char));
memcpy (Ptr->ListString, CharPtr, Length); //等同[0]~[Length-1]里放满值
*(Ptr->ListString + Length) = '\0'; //[Length]放'\0',等同补成完整string
printf ("%s", Ptr->ListString); //因为[Length]放'\0',所以可以正常显示
printf (" %d\n",Length);
作者: LPH66 (-6.2598534e+18f)   2016-02-04 00:42:00
"\0" 是 char 阵列 {(char)0, (char)0} 喔"\\0" 才是 {'\\', '0' ,'\0'}
楼主: overhead (overhead)   2016-02-04 00:52:00
呜喔!原来如此
作者: apologize (人生在世很惬意)   2016-02-04 09:20:00
受教了http://openhome.cc/Gossip/Ruby/String.html我看这个字串表示 \0 也是代表空字符阿\"表示忽略(Escape)字符
作者: ncoomb (伦)   2016-02-04 13:07:00
很用心耶。不过第二点我觉得有点要修正,就Big O来看两者相对应的memxxx和strxxx当n相同,常数忽略,二者的Big O相同。如果要细究到常数,跟平台会有关,简单说你要计算CPU二者程式全部指令集所耗T数,因CPU可能会强化一些行为,就不能看code去分析了。说错的地方在讨论吧。
作者: cobrasgo (人鱼线变成鲔鱼线,超帅)   2016-02-04 18:25:00
请爱用strn系列
作者: LPH66 (-6.2598534e+18f)   2016-02-05 00:23:00
不要随便推广 strn 系列...它反而是最需要小心使用的函式
作者: qsort (Cos)   2016-02-05 10:27:00
来用snprintf()嘛~好用耶,不试看看吗?
作者: wulouise (在线上!=在电脑前)   2016-02-05 22:05:00
不过string有分zero-terminated跟没有的吧?*null
作者: cobrasgo (人鱼线变成鲔鱼线,超帅)   2016-02-07 01:00:00
"最需要"小心使用是从何而来?我以为strn是应str的问题生出来的不是吗?对我来说看到n就知道我要注意了,光这点就完胜str系列
作者: LPH66 (-6.2598534e+18f)   2016-02-07 01:14:00
问题不在 n 而在他属于 str 系列函式所有 str 系列只有 strn 不加尾巴的 '\0'memcpy/memmove 不是 str 系列会特别注意使用状况但 str 系列因为其他都会加 '\0' 就这个不会才会说要特别注意使用
作者: cobrasgo (人鱼线变成鲔鱼线,超帅)   2016-02-08 00:36:00
都有个N了,还帮你加一个字符不是很奇怪?我知道了,这是思考逻辑的不同。你是从str系列来思考,我是从有个n来思考
作者: LPH66 (-6.2598534e+18f)   2016-02-08 01:11:00
有 n 也不一定不加喔, snprintf 就会加 '\0'
作者: cobrasgo (人鱼线变成鲔鱼线,超帅)   2016-02-09 23:59:00
脸丢大了(掩面),我的确不知道snprintf会加null囧,目前没出过问题应该是我习惯把buffer会多加一点…感谢指正

Links booklink

Contact Us: admin [ a t ] ucptt.com