4

Situation:

I'm taking a crash course to get familiar with C, and I've noticed that the author of this course can print array values beyond the array's index and be confident that the value will be 0 each time.

Code from crash course below:

int arrayVar[] = {45, 67, 34, 23};
printf("This array index value is %d", arrayVar[4]);

Output from code:

This array index value is 0

It's been my experience, during this tinkering/testing of C, that once you go beyond the array's max index, you're entering undefined behavior territory, where anything can happen, so how can he be so confident (and right) about seeing a 0 value every time?

If I print values beyond the array's max index, I see "random" values (or, values that were left there in memory, right?).

Why is my experience different from what I'm seeing in this course? Is this just a difference in C standards? Or does this indicate a difference in compilers? Or both?

Environment info : I am using the C11 standard, and I'm using the compiler that (I'm pretty sure) came default with ubuntu, located at /usr/bin/cc.

EDIT: For anyone interested in seeing what I'm seeing, here's a link to the course (you'll probably be prompted to login to Udemy): https://www.udemy.com/c-fast-crash-course-introduction/learn/lecture/12868540#questions

Sample Image

Joshua Schlichting
  • 3,110
  • 6
  • 28
  • 54
  • 3
    You are right, it is undefined behaviour. – Weather Vane Jul 20 '19 at 18:51
  • Difference in something, sure. That doesn’t seem like a very good course. – Ry- Jul 20 '19 at 18:51
  • *"... author of this course can print array values beyond the array's index and be confident that the value will be 0 each time."* - That's not correct. Holding a pointer to one element past the array in C and C++ is OK. However, you cannot dereference the pointer because that is UB. Allowing a valid pointer one past the end of the array allows loop control like `while (begin != end) { ... begin++; }`. – jww Jul 20 '19 at 18:52
  • Your teacher will continue to get zeros, until he makes a presentation to the "crash course" funding group. – Weather Vane Jul 20 '19 at 18:53
  • 2
    Instead of "crash courses", learn C from [a good book](https://stackoverflow.com/q/562303/560648). – Lightness Races in Orbit Jul 20 '19 at 18:54
  • Just because you can "predict" a 0 at the index doesn't mean it's not undefined behavior or valid. There are many cases where going beyond an index won't be 0.... – Irelia Jul 20 '19 at 18:57
  • @LightnessRacesinOrbit "C In a Nut Shell" is on the way :) I just couldn't wait to get it, and I'm really liking C so far, so I thought I'd spend my weekend tinkering with some free courses online! – Joshua Schlichting Jul 20 '19 at 18:57
  • 2
    @WeatherVane maybe there's a reason this one is free! ¯\\_(ツ)_/¯ – Joshua Schlichting Jul 20 '19 at 19:03

2 Answers2

12

The author of the course is wrong.

It's that simple.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
  • Based on the up votes, and the corroborating comments, I'm willing to accept this answer - I just have to know now, since this is the case, how is this guy getting the `0` for output in his video? Was it just by chance he got a `0`? As in, during the recording of this, a `0` was sitting in that place in memory? Is that the case? – Joshua Schlichting Jul 20 '19 at 18:59
  • 2
    Yes just chance. It's because most likely memory prior to this wasn't allocated. And some compilers might just initialise unused memory to 0. – Irelia Jul 20 '19 at 18:59
  • Alright then. I really do appreciate everyone's input on this. Thanks a lot, @Lightness Races in Orbit, and everyone else! – Joshua Schlichting Jul 20 '19 at 19:01
2
  1. Undefined does not mean random. In many cases, undefined will usually lead to some default behavior and hence may go unnoticed for a long time. Memory is commonly initialized with zeros, so accessing uninitialized memory often yields zeros. Which is why some memory debugger libraries will fill allocated memory with uncommon values such as 0xDEADBEEF that have a better chance of triggering problems.
  2. Memory allocation is nontrivial. The underlying libraries need to keep track of what is allocated vs. free, there are different kinds of allocations (stack vs. heap, data segment, BSS, ...). Libraries may have optimized strategies for allocating certain small objects, etc. - you don't call into the OS to allocate 16 bytes, but "the situation is complicated". When you allocate 16 bytes, your C library likely asks for several megabytes (if it didn't do so before), the kernel pretends it gives all this memory to the application (assuming that quite often not all of this is ever used) and the library then cuts of a chunk with your 16 bytes plus some overhead for memory management. Usually aligned to an 8 byte boundary, because micromanaging memory on the byte level is a bad idea for multiple reasons. so the next integer may be in this megabytes already allocated and cleared for future use. (Although in this particular case, the array supposedly is in the data section and never allocated, the idea is similar - there probably is some static variable next that happens to be zero. You may want to look at a dump of the binaries data segment layout.)
Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194