Reputation: 53
I have a variable that is a pointer to a constant pointer to a constant char.
char const * const * words;
I then add the word "dog" to that variable.
words = (char const * const *)"dog";
However, when when I debug the code, it states this about words:
{0x616d7251 Error reading characters of string.}
My question is, how would I properly access the characters of that variable to the point where I can record each individual character of the string.
Here is some example code below:
char const * const *words;
words = (char const * const *)"dog";
for (int i = 0; i < 5; ++i)
{
char c = (char)words[i]; // Gives me, -52'i symbol', 'd', and then '\0'
// How do I access the 'o' and 'g'?
}
Thanks for the help in advance.
Upvotes: 1
Views: 1194
Reputation: 206747
Your program has undefined behavior. To remove the undefined behavior use:
char const * word = "dog";
for (int i = 0; i < std::strlen(word); ++i)
{
char c = word[i];
}
or
char const * word = dog;
char const * const *words = &word;
for (int i = 0; i < std::strlen(*words); ++i)
{
char c = (*words)[i];
}
You are forcing a cast from char const*
to char const* const*
and treating the location of memory that was holding char
s as though it is holding char const*
s. Not only that, you are accessing memory using an out of bounds index.
Let's say the string "dog"
is held in some memory location as (it takes four bytes that includes the null character) and give it an address.
a1
|
v
+---+---+---+----+
| d | o | g | \0 |
+---+---+---+----+
You can treat the address a1
as the value of a pointer of type char const*
. That won't be a problem at all. However, by using:
words = (char const * const *)"dog";
You are treating a1
as though it is holding objects of type char const*
.
Let's assume for a moment that you have a machine that uses 4 bytes for a pointer and uses little endian for pointers.
words[0]
evaluates to a pointer. Its value will be:
'd' in decimal +
256 * 'o' in decimal +
256*256 * 'g' in decimal +
256*256*256 * '\0' in decimal.
After that, you truncate that value to char
, which will give you back the character d
, which is not too bad. The fun part (undefined behavior) begins when you access words[1]
.
words[1]
is same as *(words+1)
. words+1
evaluates to a pointer whose value is the address a2
.
a2
|
v
+---+---+---+----+
| d | o | g | \0 |
+---+---+---+----+
As you can see, it points to memory that is beyond what the compiler allocated for you. Dereferencing that pointer is cause for undefined behavior.
Upvotes: 1
Reputation: 6405
You are consistently missing the second *
.
Ignoring the const
stuff, you are declaring a char** word
, which is a pointer to a pointer to a single char. You won't get a word or many words into that, and casting just hides the problem.
To get "dog"
accessible through such a pointer, you need to take an extra step; make a variable that contains "dog"
, and put its address into your word
.
Upvotes: 1
Reputation: 50210
maybe you mean this
char const * const words = "dog";
for (int i = 0; i < strlen(words); ++i)
{
char c = words[i];
}
now of course in c++ code you should realy be using std::string
Upvotes: 4