A string literal is an array of characters* (with static storage), which contains all the characters in the literal along with a terminator. The size of an array is the size of the element multiplied by the number of elements in the array.
The literal "" is an array that consists of one char with the value 0. The type is char[1], and sizeof(char) is always one; thereforesizeof(char[1]) is always one.
In C, NULL is implementation-defined, and is often ((void*)0). The size of a void*, on your particular implementation, is 4. It may be a different number depending on the platform you run on. NULL may also expand to an integer of some type of the value 0, and you'd get the size of that instead.
*A literal is not a pointer, arrays are not pointers, pointers do not play a role in this part of the question.
Answer from GManNickG on Stack OverflowA string literal is an array of characters* (with static storage), which contains all the characters in the literal along with a terminator. The size of an array is the size of the element multiplied by the number of elements in the array.
The literal "" is an array that consists of one char with the value 0. The type is char[1], and sizeof(char) is always one; thereforesizeof(char[1]) is always one.
In C, NULL is implementation-defined, and is often ((void*)0). The size of a void*, on your particular implementation, is 4. It may be a different number depending on the platform you run on. NULL may also expand to an integer of some type of the value 0, and you'd get the size of that instead.
*A literal is not a pointer, arrays are not pointers, pointers do not play a role in this part of the question.
The empty string "" has type char[1], or "array 1 of char". It is not a pointer, as most people believe. It can decay into a pointer, so any time a pointer to char is expected, you can use an array of char instead, and the array will decay into a pointer to its first element.
Since sizeof(char) is 1 (by definition), we therefore have sizeof("") is sizeof(char[1]), which is 1*1 = 1.
In C, NULL is an "implementation-defined null pointer constant" (C99 §7.17.3). A "null pointer constant" is defined to be an integer expression with the value 0, or such an expression cast to type void * (C99 §6.3.2.3.3). So the actual value of sizeof(NULL) is implementation-defined: you might get sizeof(int), or you might get sizeof(void*). On 64-bit systems, you often have sizeof(int) == 4 and sizeof(void*) == 8, which means you can't depend on what sizeof(NULL) is.
Also note that most C implementations define NULL as ((void*)0) (though this is not required by the standard), whereas most C++ implementations just define NULL as a plain 0. This means that the value of sizeof(NULL) can and will change depending on if code is compiled as C or as C++ (for example, code in header files shared between C and C++ source files). So do not depend on sizeof(NULL).
sizeof is an operator, not a function.
You would be reminded of this if you dropped the pointless parentheses, and just wrote it:
printf("%zu", sizeof *abcp);
This also uses the C99-proper way to format a value of type size_t, which is %zu.
It works since the compiler computes the size at compile-time, without ever following (dereferencing) the pointer of course (since the pointer doesn't yet exist; the program isn't running).
sizeof is not a function and it doesn't evaluate its argument. Instead it deduces the type of *abcp, at compile time, and reports the size of that. Since abcp is a struct abc*, the type of *abcp is struct abc regardless of where abcp points.
In this Stackoverflow post[1] is stumbled upon a 'trick' to get the size of struct members like so: sizeof(((struct*)0)->member) which I struggle to comprehend what's happening here.
what I understand:
- sizeof calculates the size, as normal
- ->member dereferences as usual
what I don't understand:
- (struct*) 0 is a typecast (?) of a nullptr (?) to address 0 (?)
Can someone dissect this syntax and explain in detail what happens under the hood?
[1] https://stackoverflow.com/a/3553321/18918472
0 being an int like other integers, sizeof(0) will yield 4 bytes.
sizeof(NULL) will yield 8 bytes. In binary system, it is 8x8=64 bits, all bits with 0.
Pointers have 8 bytes allocated against characters with 1 bytes and integers 4 bytes. Is 8 bytes the maximum bytes for any datatype? I believe so as NULL is set to 8 bytes apparently for that reason to take care NULL denotes 0 for all datatypes.
I was skimming the Linux coding style guide just now and saw this:
The preferred form for passing a size of a struct is the following:
p = kmalloc(sizeof(*p), ...);
The alternative form where struct name is spelled out hurts readability and introduces an opportunity for a bug when the pointer variable type is changed but the corresponding sizeof that is passed to a memory allocator is not.
When I read that I was like, "oh that makes sense, I'll do that!" but then I thought, wait, what if the pointer has already been initialized to NULL. Is it undefined behavior? My understanding is that sizeof() doesn't actually access the value, so there won't be a dereference. Am I wrong?
sizeof(a) gives you the size of the pointer, not of the array of characters the pointer points to. It's the same as if you had said sizeof(char*).
You need to use strlen() to compute the length of a null-terminated string (note that the length returned does not include the null terminator, so strlen("abcd") is 4, not 5). Or, you can initialize an array with the string literal:
char a[] = "abcd";
size_t sizeof_a = sizeof(a); // sizeof_a is 5, because 'a' is an array not a pointer
The string literal "abcd" is null terminated; all string literals are null terminated.
You get 4 because that's the size of a pointer on your system. If you want to get the length of a nul terminated string, you want the strlen function in the C standard library.
strlen: Returns the length of the given byte string not including null terminator;
char s[]="help";
strlen(s) should return 4.
sizeof: Returns the length of the given byte string, include null terminator;
char s[]="help";
sizeof(s) should return 5.
strlen counts the elements until it reaches the null character, in which case it will stop counting. It won't include it with the length.