1) and 2) work exactly the same. Both create a 6-element non-heap-allocated array, and copy the characters 'h', 'e', 'l', 'l', 'o', '\0' to the array at runtime or load time.
3) creates an instance of std::string and calls its constructor which copies the characters 'h', 'e', 'l', 'l', 'o'(, '\0')* to its internal memory buffer. (* The '\0' is not required to be stored in the memory buffer.)
There is another way to declare a string in C++, using a pointer to char:
const char* greeting = "hello";
This will not copy anything. It will just point the pointer to the first character 'h' of the null-terminated "hello" string which is located somewhere in memory. The string is also read-only (modifying it causes undefined behavior), which is why one should use a pointer-to-const here.
If you're wondering which one to use, choose std::string, it's the safest and easiest.