Definitely not "intentional to make the program crash when things go very wrong" - they'd just call their language equivalent of exit(error_code) for that... you don't want to randomly jump somewhere in memory to cause it to crash.
Basically it means the program is trying to read a memory location outside of the range allowed it by the operating system.
This requires some kind of pointer concept in the language, and the memory address in the pointer is getting set to a bad value. This could be caused by something like forgetting to set the value of the pointer to be an address of an int it's pointing to and instead setting it to the value the int holds. This could be because of bad data / input handling - you make an array that can hold 256 bytes - and then read 265 in - and it just so happens that a pointer value was in the memory location after the array, so now data that 'spilled over' the end of the array is in the memory location where a pointer was - so next time you access that pointer - it's full of some random data, but it gets treated like a memory address. (Doing this purposefully to hack is called a 'buffer overflow attack').