C语言中访问数组不存在元素(含静态变量场景)的输出异常原因咨询
Hey there! Let's unpack exactly what's going on with your code—this is a great question that gets to the heart of how C handles memory and static variables, and it's totally normal to get tripped up by this as a CS student.
First, the Critical Background: Out-of-Bounds Access is Undefined Behavior
First things first: When you access an element beyond the declared size of an array (like c[6] when your array only has indices 0-5), this is called array out-of-bounds access, and the C standard defines this as undefined behavior. That means the compiler doesn't guarantee any specific result—your program could crash, output garbage values, or (as in your case) seem to work in a predictable way, but only by coincidence on your specific system.
Breaking Down Your Code's Execution
Let's walk through each part of your code and the output step by step:
1. Key Variables & Memory Layout
- Your
arrayis astatic intarray with 6 elements, stored in the static memory region of your program. - The
static int ainsidedo_stuffis also stored in the same static memory region (since static variables live there for the entire program lifecycle). On your compiler and system, it looks likeais placed immediately afterarrayin memory. That's the coincidence driving your output. - The local variable
bis initialized to 0 every timedo_stuffis called, soc[b]always refers toarray[0](which is 5)—that's why you see5in every second column of your output.
2. Tracking a and the Out-of-Bounds Access
Let's look at each call to do_stuff:
First call:
astarts at 0, thena +=3makes it 3.*(c+a)is*(array+3)which isarray[3](42)—that's your first output value.*(c+6)andc[6]access the memory location right afterarray[5], which is the address ofa. Sinceais now 3, you get3as the output here.- So first three lines:
42 5,3 5,3 5—this matches your result.
Second call:
aretains its value from the first call (3, since it's static), thena +=3makes it 6.- Now,
*(c+6)andc[6]still access the same memory location (the address ofa), which now holds 6. That's why you see6 5in the next three lines—this is the part you were confused about! - The
*(c+a)here is*(array+6), which is the same out-of-bounds access toa's address, so it also outputs 6.
Third call:
ais now 6, soa +=3makes it 9.- The out-of-bounds accesses now read the updated value of
a(9), hence the9 5lines.
3. Why Replacing a with a Constant Still Gave the Same Result?
When you replaced the static a with a constant 6, you were still doing an out-of-bounds access to c[6]. In that case, the memory location right after array probably happened to hold the value 6 (maybe from another static variable, or leftover memory initialization). Again, this is just a coincidence—on a different system, you might get a different value entirely.
The Big Takeaway
Never rely on the behavior of out-of-bounds array access! C doesn't perform bounds checking, so it's up to you as the programmer to ensure you only access valid indices (0 to array length - 1). The "predictable" output here is just a side effect of how your compiler arranged static variables in memory—change the compiler, add another static variable, or even reorder your code, and the result could be completely different (or even crash your program).
内容的提问来源于stack exchange,提问作者student

