This explanation from isocpp is the one that has always guided me:
Read the pointer declarations right-to-left.
* const X* p means “p points to an X that is const”: the X object can’t be changed via p.
* X* const p means “p is a const pointer to an X that is non-const”: you can’t change the pointer p itself, but you can change the X object via p.
* const X* const p means “p is a const pointer to an X that is const”: you can’t change the pointer p itself, nor can you change the X object via p.
And, oh yea, did I mention to read your pointer declarations right-to-left?
https://isocpp.org/wiki/faq/const-correctness#const-ptr-vs-p...