3

In the following code:

char *title = "VP";
printf("Sizeof title: %zd | Sizeof *title: %zd | Strlen: %zd\n", sizeof title, sizeof *title, strlen(title));

Sizeof title: 8 | Sizeof *title: 1 | Strlen: 2

It seems like the sizeof title operates on the pointer to the string (8 bytes for me), and the strlen(title) predictably gives me 2.

Why does the sizeof *title produce 1 when dereferencing the pointer rather than 3 (the byte-length of the string)? For example, why does it do that instead of what it would produce for:

printf("%zd\n", sizeof("VP"));
// 3
2
  • 1
    See How to find the 'sizeof' (a pointer pointing to an array)?. Commented Jan 16, 2021 at 6:34
  • samuelbrody1249, Since title is a pointer, not a string, why expect sizeof title to return the size of something it is not? Commented Jan 16, 2021 at 6:50

2 Answers 2

3

The size of a pointer is always the size of the pointer itself, not what it points to. That's because sizeof is mostly a compile-time operator (the result is evaluated by the compiler) and the compiler can't know what a pointer might point to at run-time.

As for sizeof *title it's the same as sizeof title[0] which is a single char. And the size of a char is 1 (it's specified to always be 1 by the way, no matter the actual bit-width).

Lastly about sizeof "VP". In C all literal strings are really arrays of characters, including the terminating null character. So the literal string "VP" is an array of three characters, hence its size is 3.


To make the answer a little bit more complete, I say that the sizeof operator is mostly compile-time. That of course can't be true for variable-length arrays, where the compiler must insert code to store the actual size of the array in a way that it can be fetched at run-time. If the array decays to a pointer, then all you have is the pointer and again sizeof returns the size of the pointer itself.

And a note about string literal arrays. While they are technically non-constant arrays, they still can't be modified. Attempting to modify a string literal leads to undefined behavior. Literal strings are thus, in effect, read-only.

Sign up to request clarification or add additional context in comments.

11 Comments

-- thanks for that. What would be the suggested way that you could do the runtime equivalent of sizeof for the above to get 3 ?
@samuelbrody1249 A variable-length array, as in size_t length = 3; char array[length]; strcpy(array, "VP"); Then sizeof array will be calculated at run-time. However, once the array has decayed to a pointer, then sizeof returns the size of the pointer.
@samuelbrody1249 All strung literals are "global", the arrays never go out of scope during the life-time of the program. So you can always use pointers to literal strings.
"they still can't be modified." --> more like "modification should not be attempted." Attempting to modify a string literal might work. It is UB.
@samuelbrody1249 There is a "signed size_t" in some operating systems. For example ssize_t which is defined in POSIX (operating systems like Linux or macOS). Then %zd is valid. But for the normal C-standard size_t it needs to be an unsigned specifier (like %zu).
|
1

The type of title is char *, so the type of *title is char, not char [3]. Thus , sizeof *title is equivalent to sizeof (char), which is 1.

title isn’t the string, it just points to the first element of the string.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.