问题
I came across these two blocks of code:
#include <stdio.h>
int main() {
int a[10], i;
for (i = 1; i <= 10; i++) {
scanf("%d", &a[i]);
printf("%d\n", a[i]);
}
return 0
}
When I run the first piece of code, the code runs well but it gets overridden at some point and I do not get the expected result.
However, when I run the second piece of code the program runs perfectly fine with no error.
#include <stdio.h>
int main() {
int size;
scanf("%d", &size);
int a[size], i;
for (i = 1; i <= size; i++) {
scanf("%d", &a[i]);
printf("%d\n", a[i]);
}
return 0
}
Why does the program run perfectly in the second case? Even in the second case, the subscript goes past the declared array size.
回答1:
Both code snippet has array out of bound access so you see undefined behavior
for(i=1;i<=size;i++)
If you have array of size 10
then the valid index is 0-9
Once we say undefined behavior then anything might happen even a crash. When you say it is working then it is just by luck you might not be seeing a crash but still you are accessing some memory which you have not allocated
回答2:
The code in the question — both variants — exhibits 'undefined behaviour' and consequently "anything is possible". That includes "the program crashes", and "the program behaves as if the overflow is legitimate" and "the program does its utmost to wipe the machine clean of all data". Fortunately, the last option is seldom exercised by compiler writers. (See also 'Nasal Demons' in the Wikipedia article.)
The code in the question — both variants — is broken. Until the for
loop is changed to the idiomatic:
for (i = 0; i < 10; i++)
the programs are simply broken, invoking undefined behaviour, and anything can happen when they're run.
If you wish, you can analyze the assembly generated for the two faulty programs if you wish (but it is better not to). My best guess as to difference in behaviour would be that the version with the constant-length array (CLA) lays out the array and index variables differently from the version with the variable-length array (VLA), so overflowing the array in the VLA version overwrites different data from overflowing the array in the CLA version.
But there's little point in investigating what happens in detail. The behaviour is undefined, and knowing what happens with one source file and one version of one compiler with one set of compilation flags on one platform won't make the code correct or reliable or portable or anything else useful. Adding a second array can alter things; changing the compiler version, using a different compiler, moving to a new platform, or changing the optimization level of the compilation — any of these can change what happens, and you have nobody to blame but yourself because the code is broken. The problem is in the code, not in what the compiler does with it.
回答3:
@Ashalynd :The operating system is Windows 8.1 and i am using CodeBlocks. The missed semicolon is a typing mistake. @JonathanLeffler :So does that mean, that the compiler behaves differently in case of Constant length array and Variable Length Array? All i want to know is that, why does the code exhibit a particular behaviour when i initialize the array size in the code itself and why does it work perfectly normal when i input the array size from the user,even though my for loop starts from 1 and not 0? I know that starting a for loop for an array with 1 is an error, which the compiler does not show, but my question is why does it behave differently in the 2 cases mentioned above in my question?
来源:https://stackoverflow.com/questions/27757562/declared-vs-non-declared-array-in-c