索引出界问题 [英] Index out of bounds question

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

问题描述

说我有以下内容:


int main(无效){

char * p,q;

p = (char *)malloc(sizeof(char)* 10);

q =(p + 100) - 99; / *合法吗? * /

免费(q - 1); / *合法吗? * /

....

返回0;

}


此程序是否总是产生UB,总是工作,还是编译器

依赖?

解决方案

Method Man写道:
< blockquote class =post_quotes>说我有以下内容:


#include< stdlib.h>
int main(int argc,char * argv []){
char * p =(char *)malloc(sizeof(char)* 10);
char * q =(p + 100) - 99; //非法!
免费(q - 1); //非法!
// ....
返回0;
}
这个程序会不会产生UB?


这是一个不正确的问题。

未定义的行为(UB)未定义。

没有特定的行为生产。

一直工作?


无处不在。

或者它是编译器依赖的吗?




没有ANSI / ISO C99兼容编译器

不接受此代码

并生成预期输出。


"方法Man < a@b.c>写道:

说我有以下内容:

int main(void){
char * p,q;


这是欺骗性的语法。它*看起来像'它意味着声明

两个指针,但它*实际上*声明一个指针和一个

整数。

p =(char *)malloc(sizeof(char)* 10);


我不建议转换malloc()的返回值:


* ANSI C中不需要强制转换。


*转换它的返回值可以掩盖#include

< stdlib.h>的失败,这会导致未定义的行为。


*如果你偶然输入了错误的类型,奇怪的失败可能会导致
结果。


其他一些人不同意,比如PJ Plauger(见文章

< 9s ***************** @nwrddc01.gnilink.net>)。


调用malloc()时,我建议在

上使用sizeof运算符,而不是类型。例如,

*不要写这个:


int * x = malloc(128 * sizeof(int)); / *不要这样做! * /


相反,请这样写:


int * x = malloc(128 * sizeof * x);


这样做有几个理由:


*如果你改变了'x'指向的类型,它'''更改malloc()调用也不需要



这在大型程序中更是一个问题,但它仍然是

方便小一点。


*考虑一个对象的大小使得编写语句

不易出错。您无需查看声明即可验证sizeof语法是否正确无误。


最后,sizeof(char)始终为1.

q =(p + 100) - 99; / *合法吗? * /


需要诊断的约束违规。见C99

6.5.16.1简单分配。此外,指针算术

会产生未定义的行为,因为你在数组中超越了

一个接一个的结尾。

免费(q - 1); / *合法吗? * /


同样违反约束条款。见C99 6.5.2.2函数调用

para 2.

....
返回0;
}
<这个程序总是会产生UB,总是工作,还是依赖于编译器?




如果没有诊断,它就不会编译。它还会产生未定义的

行为。

-

Ben Pfaff

电子邮件: bl*@cs.stanford.edu

web: http://benpfaff.org


在文章< sp ************ *****@read1.cgocable.net> ;, Method Man< a@b.c>写道:

说我有以下内容:

int main(void){
char * p,q;
p =(char *)的malloc(的sizeof(char)的* 10);


不要这样做。

这条线坏了,因为你忘了#include< stdlib.h> ;;编译器

错误地假定(根据语言定义的要求)malloc

返回int,你的演员阵容阻止它抱怨尝试

转换无效(从int到指针)。

首选形式:

p = malloc(10 * sizeof * p);

自sizeof( char)必须为1,在这种情况下你甚至可以这样做:

p = malloc(10);

q =(p + 100) - 99; / *合法吗? * /


否,但不太可能在具有平坦内存空间的系统上引起问题

和用于指针和整数运算的通用寄存器

(就是你可能使用的任何系统)。

free(q - 1); / *合法吗? * /


如果q是一个有效的指针,指向你从malloc获得的指针1(如上所述,

,这是你唯一的结果') 很可能会从上面的线上看到

以上),这是合法的,并且会完全符合您的预期。

....


格式错误的代码。

返回0;
}


这个程序是否总能产生UB,总是工作,或者是它编译器依赖吗?




总是产生UB,而且几乎总是(但编译器,更可能的是,

硬件依赖)做完全符合你的期望这是最糟糕的可能类型的UB(除了正是你所期望的,直到

有人重要的是看着)。


一个检查生成的每个指针值的系统(这样的系统在实现要求的范围内是好的,但是

我''在确定`(p + 100)''

(你要求的代码行中'' - ''运算符的左操作数后,我不确定是否存在)

about),因为这会生成一个指针,该指针在malloc分配的内存块的结尾处是90字节。大多数系统只在你取消引用它们时检查

指针(如果有的话),而不是当你创建

它们时,并且因为你从不取消引用这个特定的无效指针,

这张支票不会抓住它。

dave


-

Dave Vandervies dj ****** @ csclub.uwaterloo.ca

因为你是一个业余爱好者,我敢肯定你会想要比专业人士更好地编写代码



- 在comp.lang中的理查德希思菲尔德。 c


Say I have the following:

int main(void) {
char* p, q;
p = (char*) malloc(sizeof(char)*10);
q = (p + 100) - 99; /* legal? */
free(q - 1); /* legal? */
....
return 0;
}

Will this program always produce UB, always work, or is it compiler
dependent?

解决方案

Method Man wrote:

Say I have the following:
#include <stdlib.h>
int main(int argc, char* argv[]) {
char* p = (char*)malloc(sizeof(char)*10);
char* q = (p + 100) - 99; // illegal!
free(q - 1); // illegal!
// ....
return 0;
} Will this program always produce UB?
This is an improper question.
Undefined Behavior (UB) is undefined.
There is no specific behavior to "produce".
Always work?
It works everywhere.
Or is it compiler dependent?



There are no ANSI/ISO C99 compliant compilers
that will not accept this code
and generate the expected output.


"Method Man" <a@b.c> writes:

Say I have the following:

int main(void) {
char* p, q;
This is deceptive syntax. It *looks* like it''s meant to declare
two pointers, but it *actually* declares a pointer and an
integer.
p = (char*) malloc(sizeof(char)*10);
I don''t recommend casting the return value of malloc():

* The cast is not required in ANSI C.

* Casting its return value can mask a failure to #include
<stdlib.h>, which leads to undefined behavior.

* If you cast to the wrong type by accident, odd failures can
result.

Some others do disagree, such as P.J. Plauger (see article
<9s*****************@nwrddc01.gnilink.net>).

When calling malloc(), I recommend using the sizeof operator on
the object you are allocating, not on the type. For instance,
*don''t* write this:

int *x = malloc (128 * sizeof (int)); /* Don''t do this! */

Instead, write it this way:

int *x = malloc (128 * sizeof *x);

There''s a few reasons to do it this way:

* If you ever change the type that `x'' points to, it''s not
necessary to change the malloc() call as well.

This is more of a problem in a large program, but it''s still
convenient in a small one.

* Taking the size of an object makes writing the statement
less error-prone. You can verify that the sizeof syntax is
correct without having to look at the declaration.

Finally, sizeof(char) is always 1.
q = (p + 100) - 99; /* legal? */
Constraint violation that requires a diagnostic. See C99
6.5.16.1 "Simple assignment". Also, the pointer arithmetic
yields undefined behavior, because you''re going beyond
one-past-the-end in an array.
free(q - 1); /* legal? */
Also a constraint violation. See C99 6.5.2.2 "Function calls"
para 2.
....
return 0;
}

Will this program always produce UB, always work, or is it compiler
dependent?



It won''t compile without diagnostics. It also produces undefined
behavior.
--
Ben Pfaff
email: bl*@cs.stanford.edu
web: http://benpfaff.org


In article <sp*****************@read1.cgocable.net>, Method Man <a@b.c> wrote:

Say I have the following:

int main(void) {
char* p, q;
p = (char*) malloc(sizeof(char)*10);
Don''t Do That.
This line is broken, since you forgot to #include <stdlib.h>; the compiler
incorrectly assumes (as required by the language definition) that malloc
returns int, and your cast prevents it from complaining about attempting
an invalid conversion (from int to pointer).
Preferred form:
p = malloc(10 * sizeof *p);
Since sizeof(char) is required to be 1, in this case you can even do:
p = malloc(10);
q = (p + 100) - 99; /* legal? */
No, but unlikely to cause problems on systems with a flat memory space
and general-purpose registers used for both pointer and integer operations
(that is, pretty much any system you''re ever likely to use).
free(q - 1); /* legal? */
If q is a valid pointer to 1 past the pointer you got from malloc (which,
as noted above, is the only result you''re likely to see from the line
above), this is legal and will do exactly what you appear to expect.
....
Badly formed code.
return 0;
}
Will this program always produce UB, always work, or is it compiler
dependent?



Always produce UB, and almost always (but compiler and, more likely,
hardware dependent) do the "exactly what you expect" that''s the worst
possible kind of UB (except perhaps the "exactly what you expect, until
somebody important is watching" kind).

A system that checks every pointer value generated (such systems are
well within the bounds of the requirements on implementations, though
I''m not sure if any actually exist) can trap after evaluating `(p+100)''
(the left operand of the ''-'' operator in the line of code you''re asking
about), since this generates a pointer that''s 90 bytes past the end
of the chunk of memory allocated by malloc. Most systems only check
pointers (if at all) when you dereference them and not when you create
them, and since you never dereference this particular invalid pointer,
this check won''t catch it.
dave

--
Dave Vandervies dj******@csclub.uwaterloo.ca
Since you''re a hobbyist, I''m sure you''ll want to write the code more
correctly than a mere professional might do.
--Richard Heathfield in comp.lang.c


这篇关于索引出界问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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