# Why don’t string pointers point to the first address?

I’m trying to understand how string pointers work(std::string*).
I created an array of character pointers to a string. The string pointer for some reason points to an address that is 4 addresses before the first character’s address, but it still prints the correct string when I deference it(I guess it’s programmed to print whatever is 4 addresses from it till the null0), but why? Why 4 addresses behind, why not just start from the first character?

int main() {
std::string x = "hello";
char* ptrs[6];
for (int i = 0; i <= x.length(); i++) {
ptrs[i] = &x[i];
std::cout << (void*)ptrs[i] << "  " << *ptrs[i] << "n";
}
std::string* y = &x;
std::cout << "n" << y << "n";
std::cout << *y << "n";
std::cout << (char*)y;
return 0;
}

output:

0115F9A4  h
0115F9A5  e
0115F9A6  l
0115F9A7  l
0115F9A8  o
0115F9A9

0115F9A0
hello
╚ë2hello

Consider this very simplistic representation of the std::string container

#include <cstring>
#include <iostream>

struct StringContainer{
explicit StringContainer(const char* str) {
len_ = strlen(str);
data_ = (char*)malloc(len_);
for(int i = 0; i <len_; ++i){
data_[i] = str[i];
}
}
const char& operator[](size_t idx) {
static char nullChar = '';
return (idx < len_) ? data_[idx]: nullChar;
}

~StringContainer() {
if(data_){
free(data_);
}
}

size_t length() const {
return len_;
}
private:
char* data_;
size_t len_;
};

int main() {
StringContainer str("test");
for(int i = 0; i < str.length(); ++i) {
}
}

The container (std::string or StringContainer in the example) is a separate entity from its data. Hence the different addresses. In this example (void*)&str gives the address of the container object which encapsulates the actual string data. &str[i] gives the address of that actual string data. Using std::string that looks as follows:

#include <string>
#include <iostream>

int main() {
std::string str("test");