Too many elements in an array!

Too many elements in an array!

偏爱自由 发布于 2021-11-26 字数 494 浏览 799 回复 9 原文

Sorry if this is a noob question :( .

Piece of C code.

int array[5];
int cnt;

for(cnt = 0; cnt <= 10; cnt+=1)
{
      array[cnt] = cnt;
}

Should give an error, right? No! Works fine!
But why is that? It seems that -in the first line- an array of more than the double size (11) is defined. You can even access array[5 to 10] later on. And that is confusing me. It stops working when you define array[4 or less] ...

Thanks in advance.

如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

扫码加入群聊

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(9

别低头,皇冠会掉 2022-06-07 9 楼

Depends on how the stack memory is packed. Also, it will happily overwrite those values and even read them, but most likely you are corrupting the stack.

避讳 2022-06-07 8 楼

Once you run off the end of the array, you are overwriting memory that the software is not expecting and corrupting the heap. You software may continue to run, but it will be very unstable!

心舞飞扬 2022-06-07 7 楼

Array bounds in C are not necessarily checked at runtime. The standard leaves implementors free to do so if they choose, or not - that's part of what is undefined. On an implementation with fat pointers the sample might indeed cause some sort of error.

心碎的声音 2022-06-07 6 楼

Arrays in C are not checked at runtime. In other words, you can "define" an array of size N and happily access off of the end of the array bound. If you go off the end of the array, then you will trash memory somewhere on the stack (or the heap).

Once you trash memory somewhere, your program is likely to crash. These crashes can be hard to track down because they might crash far away from where you actually overran the end of the array.

Typically when you declare arrays in C, it's best to use some sort of constant or #define to mark the size of the array:

#define MAX_ELEMENTS 10
int array[MAX_ELEMENTS];
int cnt;
for(cnt = 0; cnt < MAX_ELEMENTS; cnt+=1) {
   array[cnt] = cnt;
}

If you go past MAX_ELEMENTS in the array assignment, you might overwrite the value of cnt. You might overwrite some other variable. All depends on the compiler and the code structure. Also note the use of the < sign in the for loop. C arrays are 0 based so you have to check using less-than and not less-than-or-equal-to.

心凉 2022-06-07 5 楼

I just like to point out that all this is indeed undefined.
Your example "works" in this specific example because both variables are located on the stack. That is the address of cnt is just below the end of the array. When cnt reaches cnt==5
the statement array[cnt]=cnt; does not write in the memory dedicated to the array but just after it, where the address of cnt lay. It is just luck that it does not alter your counter.
When cnt>5 there is no memory to trash and it will just write in the "stack void" (don't know the proper word).

another example to illustrate this:

int main(int ac,char **av)
{
    int a[5];
    int cnt;
    int cnt2=3;

    for(cnt=0;cnt<7;cnt++) {
        a[cnt]=cnt;
        printf("%d %d %dn", a[cnt], cnt, cnt2);
    }
}

output:

0 0 3
1 1 3
2 2 3
3 3 3
4 4 3
5 5 5
6 6 5

The last two writes of the loop overwrites the stack data after a[] and may yield very confusing errors. In this case the cnt2 is trashed.

明天过后 2022-06-07 4 楼

"But why is that?"

Because that's the way C is.

Array bounds are not checked at run time.

That's the "Law of the C"

命硬 2022-06-07 3 楼

What you are seeing is undefined behaviour, caused by you accessing the array with an invalid index. Undefined behaviour means that anything could happen, including your program appearing to work correctly.

风蛊 2022-06-07 2 楼

This only "works" if your definition of "works" is synonymous with "hasn't crashed yet".

稍尽春風 2022-06-07 1 楼

It may happen to work with your particular compiler and computer, but you shouldn't count on it.

The behaviour of your code according to the C language specification is undefined. This means that it might do what you hope, or it might cause your computer to crash, or it might cause demons to fly out your nose.

Unlike higher-level languages such as Java and C#, C trusts you and does not perform explicit checks on the bounds of arrays. You are supposed to be responsible and not tread outside the boundaries of the array.