越界限制? [英] Out-of-bounds Restrictions?

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

问题描述



最近在另一个帖子中,讨论过访问数组

指数超出界限。显然,以下代码是假的:


int arr [5];


arr [9] = 4;


请使用以下代码段:


int arr [2] [5];


arr [0] [9] = 4;


arr的定义导致大小的内存大小:sizeof(int)* 5

* 2

因此,我原本以为
没有任何问题
访问第10个元素(如果我们将其视为一维数组

of int')。然而,有人告诉我,行为是不确定的。


这对我来说似乎很奇怪,特别是考虑到我们应该可以访问

然而我们喜欢C中的记忆。例如,看看我们有的免费统治

如下:


int * const p = malloc(128 * sizeof * p);


p [56] = 4;


double * const pd =(double *)p;


pd [0] = 56.334;


以下代码段如何;是不确定的行为?


int(* p)[5] [6] = malloc(5 * 6 * sizeof * p);


(* p)[0] [8] = 7;


可以通过简单地添加指针来补救第二个片段吗?例如:


int arr [2] [5];


/ * arr [9] = 4; * /


int * const p =(int *)& ** arr;


p [9] = 4;


-


Frederick Gotham


In another thread recently, there was discussed the accessing of array
indices which were out of bounds. Obviously, the following code is bogus:

int arr[5];

arr[9] = 4;

Take the following snippet however:

int arr[2][5];

arr[0][9] = 4;

The definition of "arr" results in a chunk of memory of size: sizeof(int)*5
*2
Therefore, I would have thought that there was nothing wrong with the
accessing of the 10th element (if we look at it as a one-dimensional array
of int''s). I''ve been told, however, that the behaviour is undefined.

This seems strange to me, especially given that we should be able to access
memory however we like in C. For example, look at the free reign we have
with the following:

int *const p = malloc(128 * sizeof*p);

p[56] = 4;

double *const pd = (double*)p;

pd[0] = 56.334;

What about the following snippet; is the behaviour undefined?

int (*p)[5][6] = malloc(5*6*sizeof*p);

(*p)[0][8] = 7;

Can the second snippet be remedied by simply adding a pointer? e.g.:

int arr[2][5];

/* arr[9] = 4; */

int *const p = (int*)&**arr;

p[9] = 4;

--

Frederick Gotham

推荐答案

Frederick Gotham写道:
Frederick Gotham wrote:

最近在另一个线程中,讨论过访问数组

指数超出范围。显然,以下代码是假的:


int arr [5];


arr [9] = 4;


请使用以下代码段:


int arr [2] [5];


arr [0] [9] = 4;


arr的定义导致大小的内存大小:sizeof(int)* 5

* 2

因此,我原本以为
没有任何问题
访问第10个元素(如果我们将其视为一维数组

of int')。然而,有人告诉我,这种行为是不确定的。
In another thread recently, there was discussed the accessing of array
indices which were out of bounds. Obviously, the following code is bogus:

int arr[5];

arr[9] = 4;

Take the following snippet however:

int arr[2][5];

arr[0][9] = 4;

The definition of "arr" results in a chunk of memory of size: sizeof(int)*5
*2
Therefore, I would have thought that there was nothing wrong with the
accessing of the 10th element (if we look at it as a one-dimensional array
of int''s). I''ve been told, however, that the behaviour is undefined.



正确。形式上,arr [0] [9]与*(arr [0] + 9)相同,

且子表达式'arr [0] + 9''无效:它不是产生

a指向arr [0]的一个元素,也指向刚刚结束的虚构

元素(这将是arr [0] [5])。也就是说,因为你的第一个例子无效,所以
无效。


实际上,很少有C实现会抓住这个

错误:很少有C实现执行(甚至可以执行)边界 -

检查数组索引。但是,标准并未禁止

边界检查;它并没有采取实际制裁的步骤

对完美记忆的不当引用。 (这也是结构黑客的经典形式的贬值。)

Correct. Formally, arr[0][9] is identical to *(arr[0] + 9),
and the sub-expression `arr[0] + 9'' is invalid: it does not produce
a pointer to one of the elements of arr[0] nor to the fictitious
element just past its end (which would be arr[0][5]). That is, it
is invalid for the same reason your first example is invalid.

As a practical matter, few C implementations will catch this
error: few C implementations perform (or even can perform) bounds-
checking on array indices. However, the Standard does not forbid
bounds-checking; it does not take the step of actually sanctioning
an improper reference to perfectly good memory. (This is also the
downfall of the classic form of the "struct hack.")


这对我来说很奇怪,特别是考虑到我们应该能够访问内存,但我们喜欢在C中。例如,看看我们有的免费统治

以下内容:
This seems strange to me, especially given that we should be able to access
memory however we like in C. For example, look at the free reign we have
with the following:



Free rein。另外,我不太清楚你的意思是什么应该

这里:是否有潜在的道德要求?

"Free rein." Also, I''m not too sure what you mean by "should"
here: Is there a moral imperative lurking?


int * const p = malloc(128 * sizeof * p);


p [56] = 4;


double * const pd =( double *)p;


pd [0] = 56.334;
int *const p = malloc(128 * sizeof*p);

p[56] = 4;

double *const pd = (double*)p;

pd[0] = 56.334;



我不知道这应该说明什么。它是有效的

如果malloc()成功,如果sizeof(double)< = 128 * sizeof(int)。

I''m not sure what this is supposed to illustrate. It''s valid
if malloc() succeeds and if sizeof(double) <= 128 * sizeof(int).


以下代码段如何;是不确定的行为?


int(* p)[5] [6] = malloc(5 * 6 * sizeof * p);


(* p)[0] [8] = 7;
What about the following snippet; is the behaviour undefined?

int (*p)[5][6] = malloc(5*6*sizeof*p);

(*p)[0][8] = 7;



通过:p的类型为指向int [5] [6]的指针,所以

(* p)的类型为int [5] [6]和(* p)[0]的类型为int [6]

和(* p)[0] [8]是在

表示六个int数组。未定义,几乎肯定没有被捕获。


(顺便说一句,malloc()请求足够的内存为30 [/ b] b这样的int [5] [6]数组,总共900英寸。)

Work it through: p has the type "pointer to int[5][6]," so
(*p) has the type "int[5][6]" and (*p)[0] has the type "int[6]"
and (*p)[0][8] is an attempt to reference outside the extent of
that six-int array. Undefined, and almost certainly uncaught.

(By the way, the malloc() requests enough memory for thirty
such int[5][6] arrays, 900 ints altogether.)


只需添加一个指针即可修复第二个片段吗?例如:


int arr [2] [5];


/ * arr [9] = 4; * /


int * const p =(int *)& ** arr;


p [9] = 4;
Can the second snippet be remedied by simply adding a pointer? e.g.:

int arr[2][5];

/* arr[9] = 4; */

int *const p = (int*)&**arr;

p[9] = 4;



据我所知,这没问题。然而,演员是没用的

杂乱。


-

Eric Sosman
es ***** @ acm-dot-org.inva 盖子

As far as I can see, this is all right. The cast is useless
clutter, though.

--
Eric Sosman
es*****@acm-dot-org.invalid


在文章< dc ******************* @ news.indigo.ie>,

Frederick Gotham< fg *******@SPAM.com写道:
In article <dc*******************@news.indigo.ie>,
Frederick Gotham <fg*******@SPAM.comwrote:

>
在最近的另一个帖子中,讨论了数组的访问
超出界限的指数。显然,以下代码是假的:


int arr [5];


arr [9] = 4;
<然而,请看下面的片段:


int arr [2] [5];


arr [0] [9] = 4;

arr的定义导致大小的内存大小:sizeof(int)* 5
* 2
因此,我认为访问第10个元素没有任何问题(如果我们把它看成是int'的一维数组。然而,有人告诉我,这种行为是不确定的。
>
In another thread recently, there was discussed the accessing of array
indices which were out of bounds. Obviously, the following code is bogus:

int arr[5];

arr[9] = 4;

Take the following snippet however:

int arr[2][5];

arr[0][9] = 4;

The definition of "arr" results in a chunk of memory of size: sizeof(int)*5
*2
Therefore, I would have thought that there was nothing wrong with the
accessing of the 10th element (if we look at it as a one-dimensional array
of int''s). I''ve been told, however, that the behaviour is undefined.



Freddy,Freddy,Freddy,你身边的人是谁?


你完全清楚以上是未定义的因为它不是严格犹太人的b $ b。任何一天或两天读过这个团体超过

的人都是如此。关于未定义行为的基本规则就是如果你要b $ b必须要问(更确切地说,如果它甚至发生在你身上),那么它几乎肯定是


事实上,它对你所知道的每一个实现都有效的事实当然是完全无关紧要的(在宗教的眼中)

狂热者)。

Freddy, Freddy, Freddy, who''s side are you on?

You know perfectly well that the above is "undefined" because it''s not
strictly kosher. As would anyone who has read this group for more than
a day or two. The basic rule about "undefined behavior" is that if you
have to ask (more precisely, if it even occurs to you to ask), then it
almost certainly is.

The fact that it works as you expect on every implementation known to
man is, of course, completely irrelevant (in the eyes of the religious
zealots).


On Sun,29 Oct 2006 13:41:29 GMT,Frederick Gotham

< fg *** ****@SPAM.com写道:
On Sun, 29 Oct 2006 13:41:29 GMT, Frederick Gotham
<fg*******@SPAM.comwrote:

>
在最近的另一个帖子中,讨论过访问数组
索引出界。显然,以下代码是假的:


int arr [5];


arr [9] = 4;
<然而,请看下面的片段:


int arr [2] [5];


arr [0] [9] = 4;

arr的定义导致大小的内存大小:sizeof(int)* 5
* 2
因此,我认为访问第10个元素没有任何问题(如果我们把它看成是int'的一维数组。然而,有人告诉我,这种行为是不确定的。

这对我来说似乎很奇怪,特别是考虑到我们应该能够访问我们喜欢的内存。例如,看看我们的免费统治如下:


int * const p = malloc(128 * sizeof * p);

p [56] = 4;


double * const pd =(double *)p;


pd [0] = 56.334;
>
In another thread recently, there was discussed the accessing of array
indices which were out of bounds. Obviously, the following code is bogus:

int arr[5];

arr[9] = 4;

Take the following snippet however:

int arr[2][5];

arr[0][9] = 4;

The definition of "arr" results in a chunk of memory of size: sizeof(int)*5
*2
Therefore, I would have thought that there was nothing wrong with the
accessing of the 10th element (if we look at it as a one-dimensional array
of int''s). I''ve been told, however, that the behaviour is undefined.

This seems strange to me, especially given that we should be able to access
memory however we like in C. For example, look at the free reign we have
with the following:

int *const p = malloc(128 * sizeof*p);

p[56] = 4;

double *const pd = (double*)p;

pd[0] = 56.334;



仅在很可能发生的事件中,sizeof(double)< = 128 * sizeof(int)

但仍无法保证。

Only in the very likely event that sizeof(double) <= 128*sizeof(int)
but still not guaranteed.


>
以下代码段如何;是不确定的行为?


int(* p)[5] [6] = malloc(5 * 6 * sizeof * p);
>
What about the following snippet; is the behaviour undefined?

int (*p)[5][6] = malloc(5*6*sizeof*p);



这可能意味着sizeof(int),因为这样可以分配30倍的空间作为你想要的点。

You probably meant sizeof(int) here since this allocates 30x as much
space as the point you are trying to make.


>

(* p)[0] [8] = 7;
>
(*p)[0][8] = 7;



考虑一个非常专业的处理器,其中编译器识别分配给p的内存跨越内存硬件边界的
。 />
所有p [0]都在边界之前,其余部分在之后。当

为表达式生成代码时,(* p)的第一个下标是

a常量,编译器知道生成引用
$ b $的代码b纠正记忆段。在第一个下标不是常数的情况下,编译器知道生成代码以引用

" segments"并根据下标的运行时测试结果,仅执行引用正确的

段的代码。


你想要(* p) [0] [8]表示(* p)[1] [2]但代码将访问

错误的段,因为第一个下标是常量。

Consider a very specialized processor where the compiler recognizes
that the memory allocated to p straddles a "memory hardware boundary".
All of p[0] is before the boundary and the remainder is after. When
generating code for an expression where the first subscript of (*p) is
a constant, the compiler knows to generate code that references the
correct memory "segment". In the case where the first subscript is
not constant, the compiler knows to generate code to reference both
"segments" and execute only the code that references the correct
segment based on the result of a run-time test of the subscript.

You want (*p)[0][8] to mean (*p)[1][2] but the code will access the
wrong segment since the first subscript is a constant.


>
只需添加指针即可修复第二个片段吗?例如:


int arr [2] [5];


/ * arr [9] = 4; * /


int * const p =(int *)& ** arr;
>
Can the second snippet be remedied by simply adding a pointer? e.g.:

int arr[2][5];

/* arr[9] = 4; */

int *const p = (int*)&**arr;



因为** arr已经是一个int,所以不需要强制转换。或者你可以

简化为(int *)arr。

Since **arr is already an int, the cast is unnecessary. Or you could
simplify to (int*)arr.


>

p [9] = 4 ;
>
p[9] = 4;



允许编译器推断p指向arr [0]。不是以前的
更改。

删除电子邮件的del

The compiler is allowed to infer that p points into arr[0]. Not a
change from the previous.
Remove del for email


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

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