-1
#include <stdio.h>
#define CHAR_ROW_SIZE 4
int charTable[CHAR_ROW_SIZE ][2] = {
  {'X', 'Z'},
  {'J', 'L'},
  {'F', 'C'},
  {'A', 'B'}
};

int main()
{
    printf("char element %c\n", charTable[3][1]); //fine
    printf("char element %c\n", charTable[3][8]); // accessing 4th row's 9th element which is not valid 
    printf("char element %c\n", charTable[85][0]);// accessing 86th row's first element which is not valid 

    return 0;
}

Output:

char element B                                                                                                                                                                     
char element                                                                                                                                                                       
char element

As per my understanding, C\C++ doesn't actually do any boundary checking with regards to arrays. It depends on the OS to ensure that you are accessing valid memory. So it is undefined behavior.

But here I can see the constant same behavior in a different machine. i.e program doesn't crash anytime.

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
user2520119
  • 173
  • 11
  • *Undefined Behavior* is like a *box of chocolates* -- you never know what you are going to get.... See: [Undefined, unspecified and implementation-defined behavior](https://stackoverflow.com/q/2397984/3422102) and [What is indeterminate behavior in C++ ? How is it different from undefined behavior?](https://stackoverflow.com/q/11240484/3422102) and [nasal demons: n.](http://www.catb.org/jargon/html/N/nasal-demons.html) – David C. Rankin Jul 21 '20 at 07:15

2 Answers2

5

But here I can see the constant same behavior in a different machine. i.e program doesn't crash anytime.

Here, a crash (or segmentation fault) is neither the desired nor guaranteed behaviour, the behaviour is undefined.

Bottom line here is, accessing out of bound memory (i.e., the memory location which does not belong to your process address space) is undefined behaviour. Sometimes codes with UB seems to work just fine, without any segmentation fault, producing some random value, including 0, creating the illusion that things are "working fine", but they are not!

Sourav Ghosh
  • 133,132
  • 16
  • 183
  • 261
0

The C Standard has no concept of a program that "should crash", other than those which call abort();. The C Standard was written to allow implementations to process out-of-bounds array accesses in whatever way would be most useful for a compiler's customers. Depending upon what the customers are trying to accomplish, the most useful course of action might be:

  1. Trap in situations where the compiler can recognize that an out-of-bounds access is occurring.
  2. Extend the semantics of the language such that if the programmer knows what will be at the computed address, code may access that object with whatever side-effects result [and if the programmer doesn't know, code will access it anyway].
  3. Perform an access without regard for its validity, but don't allow for the possibility that the access might interact with other operations performed by the program.

When the Standard was written, there were implementations that behaved in all three ways, and programs for which each of the three ways would be most useful. Rather than trying to pass any judgments about which approach would be best in any particular situation, the authors of the Standard expected that anyone wishing to sell compilers would seek to process code in whatever fashion their customers would find most useful--a philosophy which worked well when language trends were driven by compiler writers who were beholden to their customers' interests.

supercat
  • 77,689
  • 9
  • 166
  • 211