检查memset [英] Checking memset

查看:97
本文介绍了检查memset的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

许多编译器检查printf是否有错误,lcc-win32也是如此。但还有其他值得检查的功能,特别是memset。


Memset主要用于清除内存区域,接收指向<的指针br />
开始,值(大部分时间为零)和要清除的

内存数组的大小。


问题当给定的大小不是对象的大小时出现

作为其第一个参数。例如

void fn(void)

{

int array [128];


memset(数组,0,128);

}


这将无法完全清除阵列。


当对象的大小已知时,编译器可以检查这种事情。


当指针指向一个结构/联合/或数组时已知

大小(即它的大小在编译时可用)我添加了代码

来检查这个。如果给定的大小大于

对象的大小,编译器现在将发出警告。如果大小较小,并且要设置的值为零,编译器也会发出警告,说

memset无法完全清除数组。 />

边界案例:


如何处理工会?


您可以使用memset清除工会成员,没有清除

整个工会。在这种情况下,我选择不抱怨。您怎么看?


清除阵列时会出现其他有趣的情况:


struct foo * p;

p = malloc(sizeof(struct foo)* 123);

if(p){

memset(p,0,123);

}

假设sizeof(struct foo)是64,给定的大小不是
a结构大小的倍数。

是不是可以在这里发出警告吗?或者它会导致很多误报 (无根据的警告)?


当然,当内存指向一个原始类型(int / double等)

时,编译器无法检查给出的大小是

是否正确,特别是在字符的情况下,sizeof为1.


在其他情况下它应该是倍数的元素大小,不是吗?

即清除int *时的大小应该是sizeof(int)

的倍数,其中double *是sizeof double的倍数等等。


做什么你认为?


输入赞赏。


感谢您的时间。


jacob

Many compilers check printf for errors, lcc-win32 too. But there are
other functions that would be worth to check, specially memset.

Memset is used mainly to clear a memory zone, receiving a pointer to
the start, the value (most of the time zero) and the size of the
memory array to clear.

Problems appear when the size given is not the size of the object
given as its first argument. For instance
void fn(void)
{
int array[128];

memset(array,0,128);
}

This will fail to clear the array entirely.

The compiler can check this kind of things when the size of the object
is known.

When the pointer given points to a structure/union/or array with known
size (i.e. its size is available at compilation time) I have added code
to check for this. If the size given is bigger than the size of the
object the compiler will now issue a warning. If the size is less, and
the value to set is zero, the compiler will issue a warning too, saying
that memset fails to clear completely the array.

Borderline cases:

What to do with unions?

You can use memset to clear a member of the union, without clearing the
whole union. I have choosen not to complain in this case. What do you think?

Other interesting cases arise with clearing of an array:

struct foo *p;
p = malloc(sizeof(struct foo)*123);
if (p) {
memset(p,0,123);
}
Supposing sizeof(struct foo) is 64, the given size is not
a multiple of the size of the structure.
Would it be possible to issue a warning here? or would it lead to
many "false positives" (unwarranted warnings) ?

Of course when the memory points to a primitive type (int/double, etc)
there is no way the compiler can check that the size given is
correct, specially of course in the case of chars, where sizeof is 1.

In other cases it should be a multiple of the element size, isn''t it?
I.e. the size when clearing a int * should be a multiple of sizeof(int)
with a double * a multiple of sizeof double, etc.

What do you think?

Input appreciated.

Thanks for your time.

jacob

推荐答案




jacob navia写于12/19/05 17:01,:


jacob navia wrote On 12/19/05 17:01,:
许多编译器检查printf是否有错误,lcc-win32也是如此。但还有其他值得检查的功能,特别是memset。

Memset主要用于清除内存区域,接收指向开始的指针,值(大部分时间为零)和
内存数组的大小要清除。

当给出的大小不是对象的大小时会出现问题
论点。例如
void fn(void)
{array int [128];

memset(array,0,128);
}

这将无法完全清除阵列。

当对象的大小已知时,编译器可以检查这类事情。

当指针指向具有已知
大小的结构/联合/或数组(即它的大小在编译时可用)时,我添加了代码
来检查这一点。如果给定的大小大于
对象的大小,编译器现在将发出警告。如果大小较小,并且要设置的值为零,编译器也会发出警告,说
memset无法完全清除数组。


YMMV,但我很少使用memset()并且有一个很难的时间来理解为什么它是特别的值得一试。

memcpy()和memmove()似乎更值得候选人,

并且可能会使用相同的机器。

进一步追求尺寸检查主题可能会有帮助。 qsort(),fread(),...提供机会来进行理智 - 检查多达两个参数。甚至可能更有利于理智 - 检查malloc()的参数和

calloc()和realloc()的第二个参数。由于某些信息是外部的,因此这将更加困难。

函数调用本身并且需要从

更广泛的上下文派生:`malloc(3)''孤立可能是正确的或

错了,但是`char ** p = malloc(3)''几乎肯定是错的。

边界案例:

如何处理工会?

您可以使用memset清除联盟成员,而无需清除整个联盟。在这种情况下,我选择不抱怨。你怎么看?


要填充结构或联合的一个元素,通常会写入
写memset(& s.x,42,sizeof s.x)。为了填补整个问题,

你通常会写memset(& s,42,sizeof s)。如果你要发布memset的警告(& v,42,unequal_to_sizeof_v),那么

在我看来你可以对待s或sx同样的方式。

清除数组时会出现其他有趣的情况:

struct foo * p;
p = malloc(sizeof(struct foo)* 123);
if(p){
memset(p,0,123);
}
假设sizeof(struct foo)是64,给定的大小不是
的倍数结构的大小。
是否可以在这里发出警告?或者它会导致许多误报 (无根据的警告)?


你会在结构黑客上得到误报,即使是在其获得C99批准的
C99表格中也是如此。太多?我不知道,除了我经常写相关的表格



struct foo * p = malloc(sizeof * p + strlen(s)+ 1);

if(p == NULL)die();

p-> string =(char *)(p + 1);

strcpy(p-> string,s);


....并且不想被骂。 (你可能没有

无论如何这样做,无法在编译时确定strlen(s)

时间。)


Hmmm :你考虑过检查malloc(strlen(s))吗?

当然当内存指向一个原始类型(int / double等)时,编译器无法做到检查给出的大小是否正确,特别是在字符的情况下,sizeof为1.

在其他情况下,它应该是元素大小的倍数,isn''是吗?
即清除int *时的大小应该是sizeof(int)
的倍数,其中double *是sizeof double的倍数,等等。

你怎么看?
Many compilers check printf for errors, lcc-win32 too. But there are
other functions that would be worth to check, specially memset.

Memset is used mainly to clear a memory zone, receiving a pointer to
the start, the value (most of the time zero) and the size of the
memory array to clear.

Problems appear when the size given is not the size of the object
given as its first argument. For instance
void fn(void)
{
int array[128];

memset(array,0,128);
}

This will fail to clear the array entirely.

The compiler can check this kind of things when the size of the object
is known.

When the pointer given points to a structure/union/or array with known
size (i.e. its size is available at compilation time) I have added code
to check for this. If the size given is bigger than the size of the
object the compiler will now issue a warning. If the size is less, and
the value to set is zero, the compiler will issue a warning too, saying
that memset fails to clear completely the array.
YMMV, but I use memset() rather rarely and have a hard
time understanding why it''s "specially" worthy of a check.
memcpy() and memmove() would seem more deserving candidates,
and the same machinery could probably be used.

Pursuing the size-checking theme a little further might
be helpful. qsort(), fread(), ... offer opportunities to
sanity-check as many as two arguments. It might be even
more beneficial to sanity-check the argument of malloc() and
the second arguments of calloc() and realloc(). This would
be harder because some of the information is "outside" the
function call itself and would need to be derived from the
wider context: `malloc(3)'' in isolation could be right or
wrong, but `char **p = malloc(3)'' is almost certainly wrong.
Borderline cases:

What to do with unions?

You can use memset to clear a member of the union, without clearing the
whole union. I have choosen not to complain in this case. What do you think?
To fill one element of a struct or union, one would normally
write memset(&s.x, 42, sizeof s.x). To fill the whole thing,
you''d typically write memset(&s, 42, sizeof s). If you''re going
to issue a warning for memset(&v, 42, unequal_to_sizeof_v), it
seems to me you could treat s or s.x the same way.
Other interesting cases arise with clearing of an array:

struct foo *p;
p = malloc(sizeof(struct foo)*123);
if (p) {
memset(p,0,123);
}
Supposing sizeof(struct foo) is 64, the given size is not
a multiple of the size of the structure.
Would it be possible to issue a warning here? or would it lead to
many "false positives" (unwarranted warnings) ?
You''d get false positives on the struct hack, even in its
C99-approved form. Too many? I have no idea, except that I
quite frequently write the related form

struct foo *p = malloc(sizeof *p + strlen(s) + 1);
if (p == NULL) die();
p->string = (char*)(p + 1);
strcpy(p->string, s);

.... and would not like to be scolded for it. (You might not
do so anyhow, being unable to determine strlen(s) at compile
time.)

Hmmm: Have you considered checking for malloc(strlen(s))?
Of course when the memory points to a primitive type (int/double, etc)
there is no way the compiler can check that the size given is
correct, specially of course in the case of chars, where sizeof is 1.

In other cases it should be a multiple of the element size, isn''t it?
I.e. the size when clearing a int * should be a multiple of sizeof(int)
with a double * a multiple of sizeof double, etc.

What do you think?




我认为通常负荷的胡扯;-)如何实现你的支票和运行几百万行
$ b $

通过它来源,计算误报和

实际到目前为止未被发现的错误,然后

作出判断?

-
Er ********* @ sun.com



What I think is the usual load of baloney ;-) How about
implementing your checks and running a few million lines of
source through it, counting up the false positives and the
actual hitherto-undetected errors that are caught, and then
making a judgement?

--
Er*********@sun.com


> Memset主要用于清除内存区域,接收指向
>Memset is used mainly to clear a memory zone, receiving a pointer to
的开始,值(大部分时间为零)和
内存数组的大小要清除。

当给出的大小不是对象的大小时会出现问题
论点。


小心这里的措辞,我经常给一个指针作为第一个

参数,大小不是指针*的大小*。编译器

可能仍然可以告诉指针指向的位置。

例如
void fn(void)
{
int array [128];

memset(array,0,128);
}
这将无法完全清除数组。


完全清除阵列没有错。

编译器可以在对象大小时检查这类事情
众所周知。
当指针指向具有已知
大小的结构/联合/或数组(即其大小在编译时可用)时,我添加了代码
来检查这一点。如果给定的大小大于
对象的大小,编译器现在将发出警告。


是的,这很有意义。

如果大小较小,并且
要设置的值为零,编译器将也发出警告,说是memset无法完全清除阵列。


我对这个不太确定。听起来它可能比它的价值更令人讨厌。声明

一个大缓冲区并重复使用它并不常见,使用较小的

缓冲区可能更合适,但会占用更多空间。

边界案例:

如何处理工会?

您可以使用memset清除工会成员,而无需清除<整个联盟。在这种情况下,我选择不抱怨。您怎么看?

清除数组会产生其他有趣的情况:

struct foo * p;
p = malloc(sizeof(struct foo)* 123);
if(p){
memset(p,0,123);
}
假设sizeof(struct foo)是64,给定的大小不是
结构大小的倍数。
是否可以在这里发出警告?或者它会导致许多误报 (无根据的警告)?
当然当内存指向一个原始类型(int / double等)时,编译器无法检查给定的大小是否正确,特别是当然在这种情况下of chars,其中sizeof是1.


如果已知指针指向单个变量(不是数组)

的原始类型,你可以如果尺寸

大于该变量的大小,则是相当安全的警告。

在其他情况下它应该是元素大小的倍数,不是吗?
即清除int *时的大小应该是sizeof(int)
的倍数,其中double *是sizeof double的倍数,等等。

你怎么看?
the start, the value (most of the time zero) and the size of the
memory array to clear.

Problems appear when the size given is not the size of the object
given as its first argument.
Careful with the wording here, I often give a pointer as the first
argument and the size is not the size *of the pointer*. The compiler
might still be able to tell where the pointer points, though.
For instance
void fn(void)
{
int array[128];

memset(array,0,128);
}

This will fail to clear the array entirely.
It is not wrong to fail to clear an array entirely.
The compiler can check this kind of things when the size of the object
is known. When the pointer given points to a structure/union/or array with known
size (i.e. its size is available at compilation time) I have added code
to check for this. If the size given is bigger than the size of the
object the compiler will now issue a warning.
Yes, this makes a lot of sense.
If the size is less, and
the value to set is zero, the compiler will issue a warning too, saying
that memset fails to clear completely the array.
I''m not so sure about this one. It sounds like it could be more
of a nuisance than it''s worth. It isn''t that uncommon to declare
one large buffer and re-use it multiple times where using a smaller
buffer might be more appropriate, but would take more space.
Borderline cases:

What to do with unions?

You can use memset to clear a member of the union, without clearing the
whole union. I have choosen not to complain in this case. What do you think?

Other interesting cases arise with clearing of an array:

struct foo *p;
p = malloc(sizeof(struct foo)*123);
if (p) {
memset(p,0,123);
}
Supposing sizeof(struct foo) is 64, the given size is not
a multiple of the size of the structure.
Would it be possible to issue a warning here? or would it lead to
many "false positives" (unwarranted warnings) ? Of course when the memory points to a primitive type (int/double, etc)
there is no way the compiler can check that the size given is
correct, specially of course in the case of chars, where sizeof is 1.
If the pointer is known to point to a single variable (not an array)
of primitive type, you can be fairly safe warning if the size
is larger than the size of that variable.
In other cases it should be a multiple of the element size, isn''t it?
I.e. the size when clearing a int * should be a multiple of sizeof(int)
with a double * a multiple of sizeof double, etc.

What do you think?




如果要检查memset()上的目标指针,你还需要检查memcpy()上的目标指针,strncpy( ),

memmove(),以及类似的功能。


Gordon L. Burditt



If you''re going to check the destination pointer on memset(), you
might as well check the destination pointer on memcpy(), strncpy(),
memmove(), and similar functions also.

Gordon L. Burditt




" jacob navia" < JA *** @ jacob.remcomp.fr>在留言中写道

news:43 *********************** @ news.wanadoo.fr ...

"jacob navia" <ja***@jacob.remcomp.fr> wrote in message
news:43***********************@news.wanadoo.fr...
许多编译器检查printf是否有错误,lcc-win32也是如此。但还有其他值得检查的功能,特别是memset。

Memset主要用于清除内存区域,接收指向开始的指针,值(大部分时间为零)和
内存数组的大小要清除。

当给出的大小不是对象的大小时会出现问题
论点。例如
void fn(void)
{array int [128];

memset(array,0,128);
}

这将无法完全清除阵列。

当对象的大小已知时,编译器可以检查这类事情。

当指针指向具有已知
大小的结构/联合/或数组(即它的大小在编译时可用)时,我添加了代码
来检查这一点。如果给定的大小大于
对象的大小,编译器现在将发出警告。如果大小较小,并且要设置的值为零,编译器也会发出警告,说
memset无法完全清除数组。


如果我打算警告尺寸越小条件我没有看到任何

的理由将其限制为零值。在任何情况下,这个

适用于你关于误报的问题,我要求这是

一个可以选择的选项on,而不是默认。我不熟悉你的

编译器(我知道它但没有使用它),所以这些评论是纯粹基于我想要的编译器我的b $ b使用或习惯了。

边界情况:

如何处理工会?

您可以使用memset清除成员工会,没有清除整个联盟。在这种情况下,我选择不抱怨。你认为什么是b $ b?
清除阵列会产生其他有趣的情况:

struct foo * p;
p = malloc(sizeof(struct foo)* 123);
if(p){
memset(p,0,123);
}
假设sizeof(struct foo)是64,给定的大小不是
结构大小的倍数。
是否可以在这里发出警告?或者它会导致许多误报 (无根据的警告)?

当然,当内存指向一个原始类型(int / double等)时,编译器无法检查给定的大小是否为
更正,当然特别是在字符的情况下,sizeof是1.

在其他情况下,它应该是元素大小的倍数,不是吗?
即清除int *时的大小应该是sizeof(int)
的倍数,其中double *是sizeof double的倍数,等等。

你怎么看?
<感谢您的光临。

感谢您的时间。

jacob
Many compilers check printf for errors, lcc-win32 too. But there are
other functions that would be worth to check, specially memset.

Memset is used mainly to clear a memory zone, receiving a pointer to
the start, the value (most of the time zero) and the size of the
memory array to clear.

Problems appear when the size given is not the size of the object
given as its first argument. For instance
void fn(void)
{
int array[128];

memset(array,0,128);
}

This will fail to clear the array entirely.

The compiler can check this kind of things when the size of the object
is known.

When the pointer given points to a structure/union/or array with known
size (i.e. its size is available at compilation time) I have added code
to check for this. If the size given is bigger than the size of the
object the compiler will now issue a warning. If the size is less, and
the value to set is zero, the compiler will issue a warning too, saying
that memset fails to clear completely the array.

If I were going to warn on the "size is less" condition I do not see any
reason to restrict it to the value being zero. In any case, and this
applies
to your questions about false positives below, I would require this to be
an option to be turned on, rather than default. I am not familiar with your
compiler (I am aware of it but have not used it), so these comments are
purely based on how I would like the compilers I use or have used to behave.
Borderline cases:

What to do with unions?

You can use memset to clear a member of the union, without clearing the
whole union. I have choosen not to complain in this case. What do you think?
Other interesting cases arise with clearing of an array:

struct foo *p;
p = malloc(sizeof(struct foo)*123);
if (p) {
memset(p,0,123);
}
Supposing sizeof(struct foo) is 64, the given size is not
a multiple of the size of the structure.
Would it be possible to issue a warning here? or would it lead to
many "false positives" (unwarranted warnings) ?

Of course when the memory points to a primitive type (int/double, etc)
there is no way the compiler can check that the size given is
correct, specially of course in the case of chars, where sizeof is 1.

In other cases it should be a multiple of the element size, isn''t it?
I.e. the size when clearing a int * should be a multiple of sizeof(int)
with a double * a multiple of sizeof double, etc.

What do you think?

Input appreciated.

Thanks for your time.

jacob



这篇关于检查memset的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆