This question already has answers here:
Closed 11 years ago.
Possible Duplicates:
C: differences between pointer and array
Different sizeof results
Basically, I did this...
char *str1 = "Sanjeev";
char str2[] = "Sanjeev";
printf("%d %d\n",strlen(str1),sizeof(str1));
printf("%d %d\n",strlen(str2),sizeof(str2));
and my output was
7 4
7 8
I'm not able to give reasons as to why the sizeof str1 is 4. Please explain the difference between these.
Because sizeof gives you the size in bytes of the data type. The data type of str1 is char* which 4 bytes. In contrast, strlen gives you the length of the string in chars not including the null terminator, thus 7. The sizeof str2 is char array of 8 bytes, which is the number of chars including the null terminator.
See this entry from the C-FAQ: http://c-faq.com/~scs/cclass/krnotes/sx9d.html
Try this:
char str2[8];
strncpy(str2, "Sanjeev", 7);
char *str1 = str2;
printf("%d %d\n",strlen(str1),sizeof(str1));
printf("%d %d\n",strlen(str2),sizeof(str2));
str1 is a pointer to char and size of a pointer variable on your system is 4.
str2 is a array of char on stack, which stores 8 characters, "s","a","n","j","e","e","v","\0" so its size is 8
Important to note that size of pointer to various data type will be same, because they are pointing to different data types but they occupy only size of pointer on that system.
sizeof(str1) is sizeof(char*)
whereas sizeof str2 is sizeof(char array)
sizeof(char array) should be equal to strlen(char array) + 1 (NULL termination).
Well if you pass the char array to a function, its size as shown by sizeof will change. The reason is char array is passed as char* only.
char *str1 = "Sanjeev";
printf("%d %d\n",strlen(str1),sizeof(str1));
strlen() gives the length of the string which is 7. sizeof() is a compile time operator and sizeof(str1) gives the size of pointer on your implementation (i.e 4).
char str2[] = "Sanjeev";
printf("%d %d\n",strlen(str2),sizeof(str2));
sizeof(str2) gives the size of the array which is 8*sizeof(char) i.e. 8 [including the NUL terminator]
Related
I saw here that it isn't possible to find out a (unsigned char *) string length using strlen if it isn't NULL terminated, since the strlen function will go over the string but won't find any '\0', hence a run-time error. I figure that it is exactly the same for string declared with signed char *.
I saw a code snippet that was doing something like int len = sizeof(unsigned char *); but, as I understand, it only gives the size of a pointer - word size. Is it possible to use sizeof in another way to get the result or do I have to get the length somewhere else?
Yes, you have to get the length from somewhere else. A pointer does not include length information and without a convention (e.g. last element is 0), there is no way to tell how long the array is.
non-NUL terminated string
No such thing in C. In C, by definition a string always ends with a null character.
A string is a contiguous sequence of characters terminated by and including the first null character. C11 §7.1.1 1
A string is not a pointer. A pointer may point to a string. See below for limitations.
unsigned char *s, signed char *s or char *s are all character pointers. They may contain the address of some character or have a value like NULL. As OP recognizes, sizeof s is the size of the pointer and not the size of the string.
sizeof() can be use to find the size of a string when code uses sizeof some_array_variable. The length will be 1 less than the size is select situations.
strlen() can always be used to find the length of a string. But not all arrays are strings, nor do all character pointers point to a string. See below.
char b[] below is an array and sizeof b will return 6, the size of the array in char units. When b, the formal argument, is passed to strlen(), it is converted to the address of the first element of b and strlen() uses that as its actual argument. strlen() uses that address to find the length. The length of the string is the count of characters, but not inducing the null character '\0', so the result is 5.
char *t below is a pointer assigned the address of the first character to b. Its size, system dependent, is the size of a pointer like 4,8,2, etc. strlen() uses that address like above and the result is 5.
char b[] = "Hello";
char *t = b;
printf("%zu %zu\n", sizeof b, strlen(b)); // 6 5
printf("%zu %zu\n", sizeof t, strlen(t)); // 4 5
Below, in both lines, strlen() is a problem as that function expects a pointer to a string. Instead, it receives a pointer to the beginning of a character array (size 5) that does not contain a null character. The result is undefined behavior. Code may return 5, it may return 100, it may crash the program, it may report differently tomorrow.
char d[5] = "Hello";
char *u = d;
printf("%zu %zu\n", sizeof d, strlen(d)); // 5 *
printf("%zu %zu\n", sizeof u, strlen(u)); // 4 *
In this example, the size of the array is 100, yet the string length is 5. So using sizeof(e) to find the string length does not return a +1 different answer than strlen(e).
char e[100] = "Hello";
char *v = e;
printf("%zu %zu\n", sizeof e, strlen(e)); // 100 5
printf("%zu %zu\n", sizeof v, strlen(v)); // 4 5
This question already has answers here:
Sizeof string literal
(2 answers)
Closed 9 years ago.
I have a question about how compiler stores C string?Here is some pieces of code:
#define STRING_MACRO "macro"
const char * string_const = "w";
int main(void){
printf("%u\n", sizeof(STRING_MACRO));
printf("%u\n", sizeof(string_const));
return 0;
}
output:
6
4 -- my system is x86, so it is 4
So I am confused about how compiler stores c string?Is it the same between macro style and value style?
I think most people misunderstanding my question.So I tried another code by myself.
#define TEST "a"
int main(void)
{
char hello[] = "aa";
char (*a)[10] = &hello;
printf("%u\n", sizeof(TEST));
printf("%u\n", sizeof(hello));
printf("%u\n", sizeof(*a));
return 0;
}
output:
2
3
10
So I got a conclusion the compiler store c string of macro style in char[] type, not char * type.
sizeof(STRING_MACRO);
is seen by the compiler as:
sizeof("macro");
This gives you the size of the string literal "macro", string literals are stored in an implementation defined read only region.
const char * string_const = "w";
string_cost is a pointer which points to a string literal "w".
so,
sizeof(string_const);
gives the size of the pointer i.e const char * which is apprantly 4 on your system.
sizeof() returns the object's memory size.
#define STRING_MACRO "macro"
This is 6 because the compiler allocates 6 bytes for 'macro' (5) + (1) for the string terminator
const char * string_const = "w";
This is 4 because it's a pointer, and you're working on a 32bit platform, so 4 bytes for the pointer to char.
The string "macro" is defined as a macro in your code and not as a variable.
If you build your code with gcc -E you will get a prepocessor code. and in this code you will find that
printf("%u\n", sizeof(STRING_MACRO);
is replaced with
printf("%u\n", sizeof("macro"));
the prprocessor code is the code generated by your compilator before the compilation. in this code the compilator replace the macros in your origin code with the content of the macro.
And for "w" is literal string and string_const is a pointer pointing on that literal string. and the sizeof pointer is 4 for 32-bits systems and 8 for 64-bits systems.
In your second code,
TEST is nothing but a name for a piece of code, namely the literal a. This name is expanded to the actual code during the pre-processor stage.
All string literals are NULL terminated. This is why,
sizeof("a") = 1 // the size of the character 'a'
+ 1 // size of the '\0' character
-----
= 2
"a" and "aa" are stored in read-only parts of memory (implementation defined).
hello is stored in the stack and it points to the read-only part of the memory where "aa" is stored.
Since hello is declared as a character array (whose size is implicitly 3 since no size was explicitly specified), sizeof(hello) = length of the array = length ("aa\0") = 3.
a is a pointer to a character array of length 10.
sizeof(a) would be 4 (in your x86 system) since a is a pointer.
sizeof(*a) = 10 because *a is the base pointer of the character array of length 10.
Compiler doesn't store anything. It evaluates the size of the constant during the parsing. Size of STRING_MACRO is evaluated as the length of the string + the terminator character(\0). Size of string_const is evaluated as size of pointer (because that's what it is) and on your system the pointer size is 4 bytes (corresponds to 32-bit system).
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
C -> sizeof string is always 8
I found the following way to create a string:
#include <stdio.h>
#include <string.h>
int main(void) {
char *ptr = "this is a short string";
int count = sizeof ptr / sizeof ptr[0];
int count2 = strlen(ptr);
printf("the size of array is %d\n", count);
printf("the size of array is %d\n", count2);
return 0;
}
I can't use the the usual way to get the length by sizeof ptr / sizeof ptr[0], Does this way to create string is valid? Any pros and cons about his notation?
When you do this
char *ptr = "this is a short string";
ptr is actually a pointer on the stack.
Which points to string literal on the readonly memory.
[ptr] ----> "This is a short string"
So trying to get the sizeof ptr will always evaluate to size of int on that particular
machine.
But when you try this
char ptr[]="this is a short string";
Then actually for whole string the memory is created on the stack with ptr having
starting address of the array
|t|h|i|s| |i|s| | |a| |s|h|o|r|t| |s|t|r|i|n|g|\0|
|' '| ==> this is atually a byte shown in above diagram and ptr keep the address of |t|.
So size of ptr will give you the size of whole array.
Because ptr is a pointer and not an array. If you used char ptr[] instead of char *ptr, you would have gotten an almost-correct result - instead of 22, it would have resulted in 23, since the size of the array incorporates the terminating NUL byte also, which is not counted by strlen().
By the way, "creating" a string like this is (almost) valid, but if you don't use a character array, the compiler will initialize the pointer with the address of an array of constant strings, so you should really write
`const char *ptr`
instead of what you have now (i. e. add the const qualifier).
Yes, using strlen to get the size of a string is valid. Even more, strlen is the proper way to get the size of a string. The sizeof solution here is even wrong. sizeof ptr will return 8 on 64 bits system because it is the size of a pointer, divided by the size of a char, which is 1, you will obtain only 8.
The only case where you can use sizeof to get the size of a string is when it is declared as an array of character (char[]).
This code will crash if you modify the string (because recent compilers see it as a constant). Besides, it gives incorrect results as sizeof(ptr) returns the pointer size rather than the string size.
You should rather write:
char ptr[] = "this is a short string";
Because this code will let you find the sctring length as well as modify the string contents.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Sizeof doesn't return the true size of variable in C
C -> sizeof string is always 8
Sizeof prints out 6 for:
printf("%d\n", sizeof("abcde"));
But it prints out 4 for:
char* str = "abcde";
printf("%d\n", sizeof(str));
Can someone explain why?
The string literal "abcde" is a character array. It is 6 bytes long, including the null terminator.
A variable of type char* is a pointer to a character. Its size is the size of a pointer, which on 32-bit systems is 4 bytes. sizeof is a compile time operation†, so it only looks at the variable's static type, which in this case is char*. It has no idea what's being pointed to.
† Except in the case of variable-length arrays, a feature introduced in the C99 language standard
First example, sizeof() return the length of the plain string.
Second example, sizeof() return the size of the pointer -> 32bits so 4 bytes.
Because here
printf("%d\n", sizeof("abcde"));
is a string, with considering NULL its 6 byte long.
and
char* str = "abcde";
printf("%d\n", sizeof(str));
is a pointer that requires 32bits hence 4 bytes :-)
char str[] = " http://www.ibegroup.com/";
char *p = str ;
void Foo ( char str[100]){
}
void *p = malloc( 100 );
What's the sizeof str,p,str,p in the above 4 case in turn?
I've tested it under my machine(which seems to be 64bit) with these results:
25 8 8 8
But don't understand the reason yet.
sizeof(char[]) returns the number of bytes in the string, i.e. strlen()+1 for null-terminated C strings filling the entire array. Arrays don't decay to pointers in sizeof. str is an array, and the string has 25 characters plus a null byte, so sizeof(str) should be 26. Did you add a space to the value?
The size of a pointer is of course always determined just by the machine architecture, so both instances of p are 8 bytes on 64-bit architectures and 4 bytes on 32-bit architectures.
In function arguments, arrays do decay to pointers, so you're getting the same result that you get for a pointer. Therefore, the following definitions are equivalent:
void foo(char s[42]) {};
void foo(char s[100]) {};
void foo(char* s) {};
The first is the sizeof of an built-in array, which is the amount of elements (24 + null on the end of the string).
The second is the sizeof of a pointer which is the native word size of your system, in your case 64 bit or 8 bytes.
The third is the sizeof of a pointer to the first element of an array which has the same size as any other pointer, the native word size of your system. Why a pointer to the first element of an array? Because size information of an array goes lost when passed to a function and it gets implicitly converted to a pointer to the first element instead.
The fourth is the sizeof of a pointer which has the same size as any other pointer.
str is an array of 8-bit characters, including null terminator.
p is a pointer, which is typically the size of the machine's native word size (32 bit or 64 bit).
The size taken up by a pointer stays constant, regardless of the size of the memory to which it points.
EDIT
In c++, arguments that are arrays are passed by reference (which internally is a pointer type), that's why the second instance of str has sizeof 8.
in the cases the size of
char str[] = “ http://www.ibegroup.com/”
is known to be 25 (24+1), because that much memory is actually allocated.
In the case of
void Foo ( char str[100]){
no memory is allocated