If pos is less or equal to the string length, the function never throws exceptions (no-throw guarantee).
Otherwise, it causes undefined behavior.
Note that using the reference returned to modify elements that are out of bounds (including the character at pos) also causes undefined behavior.
Your original code doesn't work because you were not allocating the memory, you were trying to access character elements that did not exist. You could of wrote
1 2 3 4 5 6 7 8 9
string name;
name.resize(4); //provide space for 4 characters
name[0]='m';
name[1]='a';
name[2]='r';
name[3]='k';
for(int i=0; i<4; i++)
cout<<name[i];
When you write string name = "mark"; The constructor is invoked and reserves the memory automatically.