关于网友提出的“ 一个buff是不是用memset比较安全”问题疑问,本网通过在网上对“ 一个buff是不是用memset比较安全”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:
问题: 一个buff是不是用memset比较安全
描述: char retbuff[100] = {0};
我一般是像上面那样去定义一个buff来用,也就是定义后紧接着 = {0}去清空,紧着着我就可以用这个buff了。我以前的同事也时经常这样用的。
但是最近我一个同事说,这样用不太安全。他说最好是char retbuff[100];然后memset(retbuff,0,100);再用它就比较安全了。我不知道他说的有没有道理,因为我觉得两者没啥区别啊,怎么会不安全呢,当然,如果我其他地方再用这个buff时,我知道是该用memset的。
我的同事说的有无道理,特地向大家请教下。
解决方案1:
这个说法也对的。
一个是编译器是确定的,一个是运行时赋值。
不过看具体情况。目前还没有遇到有什么特殊的问题的,两种情况几乎等价。
如果C/C++标准突然改变,兴许会有不同的。
解决方案2: {0} 高效 memset 低效.
解决方案3: 是的,这是个好习惯。
解决方案4:
memset怎么会发生非标准行为? 这是标准C库函数吧~~~
另外boy前辈,我那个送给新手的帖子里,后面问了您几个问题,帮忙解答下吧~~
解决方案5: 最好是用memset来清空吧。
解决方案6: 要用确定的方法,而不是依赖编译器以及未定义行为。
解决方案7: 呃。。
指定地址之后的指定长度,都被填充为指定的值。
解决方案8: 就像1楼说的。
{}是编译器实现的,好像没有规定说一个编译器实现{0}时,
必须使用0对buff缓冲区进行全部填充,所以可能会出现不同的行为。
而memset是标准C库函数,无论在哪个环境,这个函数实现的功能都是
设置目标缓冲区位指定长度的值。
解决方案9: 关于char retbuff[100] = {0};不安全的是讹传。我举个在网上搜到的例子:
问:
...
wchar_t wname[128]=...{0};
char cname[256]=...{0};
...
我感兴趣的是:
1.这种赋值的结果.
2.这种形式是否符合标准编码规则?
答:
/*
初始化值的个数可少于数组元素个数.当初始化值的个数少于数组元素个数时,前面的按序初始化相应值, 后面的初始化为0(全局或静态数组)或为不确定值(局部数组).
*/
我相信上面的资料是C和C++语言的标准规范,但实际编译器处理时,可能会和规范有所不同.因为编译器原则上要遵从语言规范,但对于局部数组的不确定值到底是多少,怎么处理,编译器就可以灵活处理.我测试了三种编译器,其实编译器赋予的值是固定的,都是0.
在这篇blog中 http://hi.baidu.com/widebright/blog/item/a024bc09631402256b60fbd0.html 谈论了相同的话题
但是,回答者显然没有看过或者没有看懂C/C++标准,C90是这样说的:
6.57 Initialization
...
If there are fewer initializers in a brace-enclosed list than there are members of an aggregate, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
那么objects that have static storage duration是如何进行初始化呢,有明确规定:
If an object that has static storage duration is not initialized explicitly. it is
initialized implicitly as if every member that has arithmetic type were assigned 0 and every member that has pointer type were assigned a null pointer constant.
对于数值类型就用0初始化,对于指针用空指针常量。而C99也有类似的内容:
6.7.8 Initialization
......
If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.
.....
If an object that has static storage duration is not initialized explicitly,
then:
— if it has pointer type, it is initialized to a null pointer;
— if it has arithmetic type, it is initialized to (positive or unsigned) zero;
— if it is an aggregate, every member is initialized (recursively) according to these rules;
— if it is a union, the first named member is initialized (recursively) according to these rules.
C++则是这样规定的:
8.5 Initializers
8.5.1 Aggregates
If there are fewer initializers in the list than there are members in the aggregate, then each member not explicitly initialized shall be value-initialized (8.5). [Example:
struct S { int a; char* b; int c; };
S ss = { 1, "asdf" };
initializes ss.a with 1, ss.b with "asdf", and ss.c with the value of an expression of the form int(), that is, 0. ]
那个回答之所以是错的,是以为它遵循If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.这条规定,实则不是,对于初始化器不足聚集元素数量的初始化是另有规定的。
解决方案10: 对第一种初始化方式的担忧来源于某些编译器可能不会将后部的元素进行char()初始化,但我认为这种担忧是多余的,因为无论c还是c++,值初始化都是受标准支持的,都是标准明文规定的条款,对于内置类型,值初始化就是数值0,对于类,就是默认构造函数。
后部元素不进行值初始化就属于非标准行为了,不应该将非标准行为归咎于初始化方式,因为,如果将非标准行为归咎为原因的话,memset同样可能发生非标准行为。
解决方案11: 没有任何问题!否则请举出反例来。
解决方案12: char retbuff[100] = {0};
一般也就编译成
先
retbuff[0] = 0;
给第一个元素赋值
然后memset之后那99个元素
解决方案13:
这个还是查一下标准吧。{};应该是默认构造函数吧。int();char()之类的都是0吧。
解决方案14: 用memset()不安全,如果不是char类型,又要计算他的大小。像这样:
memset(retbuff,0,100*sizeof(T));
如果你的retbuff是静态的,那么就应该memset();因为可能上次有人访问过它、
解决方案15: 有道理,{}是编译器问题,memset那就是个确定的函数。
以上介绍了“ 一个buff是不是用memset比较安全”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3784934.html