-
char * array and sizeof
Hi there. I'm trying to understand this code to get a better idea of pointers.
My question is why the value of sizeof(pstr[0]) is 4 rather than 15 ("Robert Redford" + '\0')?
And strlen works fine here. Should I trust it more than sizeof?
Code:
#include <iostream>
using std::cout;
#include<cstring>
using std::strlen;
int main()
{
char* pstr[] = { "Robert Redford",
"Hopalong Cassidy",
"Lassie",
"Slim Pickens",
"Boris Karloff",
"Oliver Hardy"
};
cout<<pstr[0]; //pstr[0] is non-const pointer to const char array "Robert Redford"
cout<<sizeof(pstr[0]);
cout<<strlen(pstr[0]);
getchar();
return 0;
}
Notice that this program works fine in DEV-C++
(while in MS Visual I get an error that strlen is not member of std; weird)
-
Code:
2.2: But I heard that char a[] was identical to char *a.
Not at all. (What you heard has to do with formal parameters to functions; see question 2.4.) Arrays are not pointers. The array declaration "char a[6];" requests that space for six characters be set aside, to be known by the name "a." That is, there is a location named "a" at which six characters can sit. The pointer declaration "char *p;" on the other hand, requests a place which holds a pointer. The pointer is to be known by the name "p," and can point to any char (or contiguous array of chars) anywhere.
As usual, a picture is worth a thousand words. The statements
char a[] = "hello";
char *p = "world";
would result in data structures which could be represented like this:
+---+---+---+---+---+---+
a: | h | e | l | l | o |\0 |
+---+---+---+---+---+---+
+-----+ +---+---+---+---+---+---+
p: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
It is important to realize that a reference like x[3] generates different code depending on whether x is an array or a pointer. Given the declarations above, when the compiler sees the expression a[3], it emits code to start at the location "a," move three past it, and fetch the character there. When it sees the expression p[3], it emits code to start at the location "p," fetch the pointer value there, add three to the pointer, and finally fetch the character pointed to. In the example above, both a[3] and p[3] happen to be the character 'l', but the compiler gets there differently. (See also questions 17.19 and 17.20.)
2.6: Why doesn't sizeof properly report the size of an array which is a parameter to a function?
The sizeof operator reports the size of the pointer parameter which the function actually receives (see question 2.4).
Basically, you're taking the sizeof a pointer, rather than the array that it points to.
-
Thanks for your help. Although your answer is well stated I can't understand it very well.
It sounds funny but I think I get everything
except for your last sentence(and most important)
Can you give me a link for the "see question" that you write?
-
pstr is an array of pointers. So, every element in the pstr array is a pointer. When you write:
sizeof(pstr[0]);
you are asking for the size of the first pointer in the array. Pointers store addresses in memory. Try this:
Code:
int num = 10;
int* ptr = #
cout<<ptr<<endl;
You won't get 10 as the output--you'll get the address in memory where 10 is stored as the output--something like 006BFDC8. The sizeof a pointer is the sizeof the address 006BFDC8, which is an integer written in hexidecimal notation.
-
Ooops. I intended to do that.
http://www.lysator.liu.se/c/c-faq/c-2.html
So basically, to just simulate that ASCII art they had, in your case you have
Code:
+-----+ +---+---+---+---+---+---+
pstr[0]: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
+-----+ +---+---+---+---+---+---+
pstr[1]: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
+-----+ +---+---+---+---+---+---+
pstr[2]: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
+-----+ +---+---+---+---+---+---+
pstr[3]: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
+-----+ +---+---+---+---+---+---+
pstr[4]: | *======> | w | o | r | l | d |\0 |
+-----+ +---+---+---+---+---+---+
So when you take sizeof(pstr[x]) then you just get the size of that pointer. When you say strlen(pstr[x]), the function calculates how many character's lie before a null-terminator '\0' in the array that pstr[x] points to.
-
Of course to get the thing a pointer points to, you can dereference the pointer with '*', like so:
*pstr[0]
So you might try:
cout<< sizeof *pstr[0];
However, a pointer to a string points to the first char in the string, so you will end up getting the size of the first character, which is 1.
The botton line is: when you want to get the length of a cstyle string, you should use strlen().
-
Thanx both of you for your answers.
The helped me get a better idea.