Указатели на память в стеке?
Итак. В присваивании у нас участвует "string" - это константа. Она отправляется компилятором в область данных программы - это зависит от платформы, куда конкретно. Так что на стеке оказывается сам указатель cStr, который указывает куда-то, куда компилятор засунул ваши буковки.
По второму вопросу (какого черта вы засунули два вопроса в один?) - компилятор - не дурак, он взял два одинаковых набора символов "str", понял, что они одинаковые, и не стал плодить дубляки - в a и b попадает один указатель, потому как компилятор не стал сохранять в программе две идентичные строки.
Почему при выводе, напримерstd :: cout << cStr ;
Выводится "string" , то есть значение, а не адрес значения как обычно с указателями ?
Потому что в cout переопределена оператор << для типа char*, так чтобы  выводилась именно строка, а не указатель. Чтоб вывести адрес преобразуйте указатель в int и выводите как целое число.