memset()的一个怪异的用法(高手进)

时间:2021-09-23 18:55:38
。。。
pAttachFile[i].pszAttachFileName = new TCHAR[ MAX_PATH];
memset(pAttachFile[i].pszAttachFileName, 0,  MAX_PATH*2);
_tcscpy_s(pAttachFile[i].pszAttachFileName, MAX_PATH, m_arrAttach.GetAt(i));
。。。

以上是我从一段代码中节录的一段,
红色部分是我有疑问的地方,
第一个红色部分new出了MAX_PATH个TCHAR内存空间,
第二个怎么能将MAX_PATH*2个TCHAR内存空间初始化为NULL呢?

这样做的用意是什么呢?

22 个解决方案

#1


楼主去看看unicode和ansi吧。
unicode的编码一个字符占2byte,ansi占一个byte。

#2


TCHAR是w_char宽字节。也是占2个byte。

#3


楼主碰到这种代码,打个问号是完全有意义的。
这种代码就是埋个地雷,指不定哪天就炸了(用非unicode方式编译时会“爆炸”)

应该写 
memset(pAttachFile[i].pszAttachFileName, 0, MAX_PATH *  sizeof(TCHAR) );

#4


TCHAR是自适应的,在vc6下占一个字节,vs2008占两个。默认情况。

#5


(1):如果你是用的是UNICODE编程,那么TCHAR应该是short类型,占两个字节,MAX_PATH个TCHAR就是2*MAX_PATH个字节,所以memset可以将以pAttachFile[i].pszAttachFileName为开始的地址,长度为 MAX_PATH*2个字节的内存置0是没问题的,
(2):如果你用的不是UNICODE编码,那么你上面的代码会出现越界,后果无法预料,可能崩溃,也可能表面没什么异常

完美的解决办法是memset(pAttachFile[i].pszAttachFileName, 0, MAX_PATH*sizeof(TCHAR));

#6


楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

#7


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

......

#8


这不是什么怪异用法却是错误的用法,其在于误认为TCHAR固定2Byte,而忽略了为char时占1个字节可能存在的溢出问题。还有,因为随及调用的了wcscpy所以此处内存不初始化填0亦可。但是不提倡6L的用法(想想为什么?)

#9


引用 8 楼  的回复:
这不是什么怪异用法却是错误的用法,其在于误认为TCHAR固定2Byte,而忽略了为char时占1个字节可能存在的溢出问题。还有,因为随及调用的了wcscpy所以此处内存不初始化填0亦可。但是不提倡6L的用法(想想为什么?)
是不是因为pAttachFile[i].pszAttachFileName[0] = '\0'

而pAttachFile[i].pszAttachFileName[1] 却不是为 '\0'?

#10


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

你也开始扯淡了

#11


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

 
  对于长的字符串,这种方法的确是非常好的方法,效率非常高。
++

#12


这雷埋的浅,肉眼能看出来
有的不炸个好歹的根本不知道啊,呵呵

#13


该回复于2012-07-20 08:30:29被版主删除

#14


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举


牛...

#15


那对C-Style字符串截尾固然好用,但切不可以用以初始化,且从上下文看无任何意义(该字符串在strcpy之前未被使用)。

#16


引用 3 楼  的回复:
楼主碰到这种代码,打个问号是完全有意义的。
这种代码就是埋个地雷,指不定哪天就炸了(用非unicode方式编译时会“爆炸”)

应该写 
memset(pAttachFile[i].pszAttachFileName, 0, MAX_PATH * sizeof(TCHAR) );

support

#17


引用 15 楼  的回复:
那对C-Style字符串截尾固然好用,但切不可以用以初始化,且从上下文看无任何意义(该字符串在strcpy之前未被使用)。


???
C-Style字符串,str[0] = '\0' 方式清空,不是最自然和有效的初始化吗?

为什么“不可以用以初始化”?说说理由?

#18


引用 2 楼  的回复:
TCHAR是w_char宽字节。也是占2个byte。


+1

#19


意见都是一致的了,就是这个代码是错误的。没有充分考虑TCHAR的大小。

#20


引用 11 楼  的回复:
引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

 
  对于长的字符串,这种方法的确是非常好的方法,效率非常高。
++

效率是高了,但是发生错误的可能性也高了.

#21


引用 20 楼  的回复:
效率是高了,但是发生错误的可能性也高了.


错误之所以发生,是因为原本就有错误。

这个是哲学问题,
你也可以理解为,“暴露错误的可能性提高”。
这是好事。

这里换用memset的话,换句话说,一定程度上能“掩盖错误”。

用这些方式企图降低错误率,实乃“掩盖错误”,属歪门邪道,
不利于程序调试。

而错误。。总会在不经意间又冒出来,这时候,
当你抓bug抓的焦头烂额时,你就会发现,
企图掩盖错误,是多么荒谬。

这是鄙人的一点小经验。





#22


分配 有充足的空间存存储路径

#1


楼主去看看unicode和ansi吧。
unicode的编码一个字符占2byte,ansi占一个byte。

#2


TCHAR是w_char宽字节。也是占2个byte。

#3


楼主碰到这种代码,打个问号是完全有意义的。
这种代码就是埋个地雷,指不定哪天就炸了(用非unicode方式编译时会“爆炸”)

应该写 
memset(pAttachFile[i].pszAttachFileName, 0, MAX_PATH *  sizeof(TCHAR) );

#4


TCHAR是自适应的,在vc6下占一个字节,vs2008占两个。默认情况。

#5


(1):如果你是用的是UNICODE编程,那么TCHAR应该是short类型,占两个字节,MAX_PATH个TCHAR就是2*MAX_PATH个字节,所以memset可以将以pAttachFile[i].pszAttachFileName为开始的地址,长度为 MAX_PATH*2个字节的内存置0是没问题的,
(2):如果你用的不是UNICODE编码,那么你上面的代码会出现越界,后果无法预料,可能崩溃,也可能表面没什么异常

完美的解决办法是memset(pAttachFile[i].pszAttachFileName, 0, MAX_PATH*sizeof(TCHAR));

#6


楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

#7


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

......

#8


这不是什么怪异用法却是错误的用法,其在于误认为TCHAR固定2Byte,而忽略了为char时占1个字节可能存在的溢出问题。还有,因为随及调用的了wcscpy所以此处内存不初始化填0亦可。但是不提倡6L的用法(想想为什么?)

#9


引用 8 楼  的回复:
这不是什么怪异用法却是错误的用法,其在于误认为TCHAR固定2Byte,而忽略了为char时占1个字节可能存在的溢出问题。还有,因为随及调用的了wcscpy所以此处内存不初始化填0亦可。但是不提倡6L的用法(想想为什么?)
是不是因为pAttachFile[i].pszAttachFileName[0] = '\0'

而pAttachFile[i].pszAttachFileName[1] 却不是为 '\0'?

#10


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

你也开始扯淡了

#11


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

 
  对于长的字符串,这种方法的确是非常好的方法,效率非常高。
++

#12


这雷埋的浅,肉眼能看出来
有的不炸个好歹的根本不知道啊,呵呵

#13


该回复于2012-07-20 08:30:29被版主删除

#14


引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举


牛...

#15


那对C-Style字符串截尾固然好用,但切不可以用以初始化,且从上下文看无任何意义(该字符串在strcpy之前未被使用)。

#16


引用 3 楼  的回复:
楼主碰到这种代码,打个问号是完全有意义的。
这种代码就是埋个地雷,指不定哪天就炸了(用非unicode方式编译时会“爆炸”)

应该写 
memset(pAttachFile[i].pszAttachFileName, 0, MAX_PATH * sizeof(TCHAR) );

support

#17


引用 15 楼  的回复:
那对C-Style字符串截尾固然好用,但切不可以用以初始化,且从上下文看无任何意义(该字符串在strcpy之前未被使用)。


???
C-Style字符串,str[0] = '\0' 方式清空,不是最自然和有效的初始化吗?

为什么“不可以用以初始化”?说说理由?

#18


引用 2 楼  的回复:
TCHAR是w_char宽字节。也是占2个byte。


+1

#19


意见都是一致的了,就是这个代码是错误的。没有充分考虑TCHAR的大小。

#20


引用 11 楼  的回复:
引用 6 楼  的回复:
楼上,还有更完美的解决办法,就是不用memset,直接写
pAttachFile[i].pszAttachFileName[0] = '\0'

反正就是字符串清空,用memset用此一举

 
  对于长的字符串,这种方法的确是非常好的方法,效率非常高。
++

效率是高了,但是发生错误的可能性也高了.

#21


引用 20 楼  的回复:
效率是高了,但是发生错误的可能性也高了.


错误之所以发生,是因为原本就有错误。

这个是哲学问题,
你也可以理解为,“暴露错误的可能性提高”。
这是好事。

这里换用memset的话,换句话说,一定程度上能“掩盖错误”。

用这些方式企图降低错误率,实乃“掩盖错误”,属歪门邪道,
不利于程序调试。

而错误。。总会在不经意间又冒出来,这时候,
当你抓bug抓的焦头烂额时,你就会发现,
企图掩盖错误,是多么荒谬。

这是鄙人的一点小经验。





#22


分配 有充足的空间存存储路径