I'm teaching myself C++ and I'm a bit confused about pointers (specifically in the following source code). But first, I proceed with showing you what I know (and then contrasting the code against this because I feel as if there are some contradictions going on).
What I know:
int Age = 30;
int* pointer = &Age;
cout << "The location of variable Age is: " << pointer << endl;
cout << "The value stored in this location is: " << *pointer << endl;
Pointers hold memory addresses. Using the indirection (dereference) operator (the *), you can access what is stored in memory location of the pointer. Onto the code in this book I'm having trouble understanding...
cout << "Enter your name: ";
string name;
getline(cin, name); //gets full line up to NULL terminating character
int CharsToAllocate = name.length() + 1; //calculates length of string input
//adds one onto it to adjust for NULL character
char* CopyOfName = new char[CharsToAllocate];
// pointer to char's called CopyOfName, is given the memory address of the
//beginning of a block
//of memory enough to fit CharsToAllocate. Why we added 1? Because char's need a
//NULL terminating character (\0)
strcpy(CopyOfName, name.c_str()); //copies the string name, into a pointer?
cout << "Dynamically allocated buffer contains: " << CopyOfName << endl;
delete[] CopyOfName; //always delete a pointer assigned by new to prevent memory leaks
Output:
Enter your name: Adam
Dynamically allocated buffer contains: Adam
The comments in the above code are my comments. My problem begins with strcpy
. Why is name.c_str()
copied into a pointer CopyOfName
? Does this mean that all strings are essential pointers? So like
string testing = "Hello world";
Is actually a pointer pointing to the memory location where "H" is stored?
Next, why is it in the print out statement using CopyOfName
and not *CopyOfName
? Pointers hold memory addresses? Using *CopyOfName
would print out the contents of the memory location. I tried this in Code::Blocks and if the input text was "Hello World." Using *CopyOfName
in the print out statement would just give an "H". This makes sense since when I declared that I needed a memory block with the 'new' thing, this actually returns a pointer to the first part of the dynamically allocated memory block.
The only way I can reconcile this is if a string is actually a pointer.
string testing = "Confused";
cout << testing << endl;
would print out the word "Confused"
However, if I try to compile
string testing = "Confused";
cout << *testing;
I get an error message.
Basically, to summarize my question, I'm trying to understand the code with strcpy
and the cout
statement.
String is a data type that stores the sequence of characters in an array. Every string terminates with a null character (\0), indicating its termination. A pointer to string in C can be used to point to the base address of the string array, and its value can be dereferenced to get the value of the string.
Accessing string using pointer Using char* (character pointer), we can access the string.
A string constant in C is represented by a sequence of characters within double quotes. Standard C character escape sequences like \n (newline), \r (carriage return), \a (bell), \0x17 (character with hexadecimal code 0x17), \\ (backslash), and \" (double quote) can all be used inside string constants.
It seems like you understand what C-style strings are, but to summarize, they are just arrays of characters in memory, by convention terminated by a nul character \0
. Usually they are referenced via a char*
pointing to the first letter in the string. When they are printed, typically the characters of the string are printed starting from the first, and printing (or copying, etc.) stops when the \0
terminator is reached.
An std::string
is a class that (typically) wraps a C-style string. This means that a std::string
object (typically) has a private C-style string that is used to implement its functionality. The function std::string::c_str()
returns a pointer to this underlying C-style string.
Let's suppose that char *str;
points to a C-style string. If you attempt to run cout << *str << endl;
, you noticed that only the first character is printed. That is because of C++'s function overloading. The data type of *str
is char
, so the char
version of cout
is called and faithfully prints the single character *str
. For compatibility with C-style strings, the version of cout
that takes a char*
as an argument treats the pointer as a C-style string for printing purposes. If you cout
an int*
, for example, the underlying int
will not be printed.
Edit: Another comment:
The reason that your attempt to dereference an std::string
object failed is that, indeed, it is not a pointer. You could dereference the return value of std::string::c_str()
, and you would get back the first char
of the string.
Related: How is std::string implemented?.
In C, strings are simply arrays of characters. And arrays decay to pointers when used as the argument to a function.
In C++, std::string
is a class. It includes a C-style character array within it, and this is what c_str()
returns. But the string itself is not a pointer, so you can't dereference it; you have to use the c_str()
method to get a pointer to the string contents.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With