I am probably answering my own question here but I will leave this open in case anybody else gets benefit from it,
I think the reason it is crashing is because 'a' 'd' and 'a' and rvalues are temporary literals, so *points[0] to [3] are or could be pointing to invalid memory right?
It's certainly true that every char* in the array is pointing at random memory when you create them, and points[3] is until you set it to point at char b.
As such, you're writing over random memory, and then reading and outputting random memory. ANything could happen.
Nothing to do with 'a' and 'd' being rvalues. You're simply writing the char 'a' and the char 'd' into random memory.
N.B.: If you're using print statements to track control-flow through a program which is crashing, use std::cerror std::clog instead of std::cout. std::cout writes to an internal buffer before the output device, so you might not see the message immediately after it is printed. std::cerrand std::clog, on the other hand, bypass any internal buffer and make the output visible immediately, on stderr and stdout, respectively.
This creates an array. The array contains four char-pointers. Each char-pointer has a value. You didn't set the value; each char-pointer's value is whatever happened to be in the memory that is now an array. Random values.
So, each of the four char-pointers is pointing into random memory.
*points[0] = 'a';
This says "the char-pointer in the first element of the array, the first char pointer, that's pointing at some random memory; write the character 'a' into that random memory."
So that's how.
Is that clear enough?
Maybe you're mixed up between "a" and 'a'.
"a" is a char-pointer, pointing at a byte of memory that contains the char 'a'. This is known as a string literal. 'a' is the char 'a'.