string a= "Stack Overflow";
char b[]= "Stack Overflow";
cout<<sizeof(a)<<","<<sizeof(b)<<endl;
Output of above code is 4,15
Since 'a' points to the string, it has size 4 that of a string on my machine.
'b' is also pointer to string, but why it has size of 15 (i.e. of sizeof("Stack Overflow")) ?
Since 'a' points to the string, it has size 4 that of a string on my machine.
Not exactly.
a IS A string. It is not a pointer and, hence, does not point to a string. The implementation of string on your setup is such that sizeof(string) is 4.
'b' is also pointer to string, but why it has size of 15 (i.e. of sizeof("Stack Overflow")) ?
Not true.
b is not a pointer to a string. It is an array of char. The line
char b[]= "Stack Overflow";
is equivalent to:
char b[15]= "Stack Overflow";
The compiler deduces the size of the array and creates an array of the right size.
Related
#include <cstdlib>
#include <iostream>
int main(int argc, char *argv[])
{
cout << "size of String " << sizeof( string );
system("PAUSE");
return EXIT_SUCCESS;
}
Output:
size of String = 4
Does that mean that, since sizeof(char) = 1 Byte (0 to 255), string can only hold 4 characters?
It isn't clear from your example what 'string' is. If you have:
#include <string>
using namespace std;
then string is std::string, and sizeof(std::string) gives you the size of the class instance and its data members, not the length of the string. To get that, use:
string s;
cout << s.size();
When string is defined as:
char *string;
sizeof(string) tells you the size of the pointer. 4 bytes (You're on a 32-bit machine.) You've allocated no memory yet to hold text. You want a 10-char string? string = malloc(10); Now string points to a 10-byte buffer you can put characters in.
sizeof(*string) will be 1. The size of what string is pointing to, a char.
If you instead did
char string[10];
sizeof(string) would be 10. It's a 10-char array.
sizeof(*string) would be 1 still.
It'd be worth looking up and understanding the __countof macro.
Update: oh, yeah, NOW include the headers :) 'string' is a class whose instances take up 4 bytes, that's all that means. Those 4 bytes could point to something far more useful, such as a memory area holding more than 4 characters.
You can do things like:
string s = "12345";
cout << "length of String " << s.length();
sizeof(char) is always 1 byte. A byte which we think is 8-bits need not be the case. There are architectures where a BYTE is 32-bits, 24-bits and so on. The sizeof applied to any other type is in multiples of sizeof(char) which is by definition 1.
The next important thing to note is that C++ has three character types: plain char, signed char and unsigned char. A plain char is either signed or unsigned. So it is wrong to assume that char can have only values from 0 to 255. This is true only when a char is 8-bits, and plain char is unsigned.
Having said, that assuming that 'string' is 'std::namespace', sizeof(string) == 4 means that the sizeof the 'std::string' class is 4 bytes. It occupies 4 times the number of bytes that a 'char' on that machine takes. Note that signed T, unsigned T always have the same size. It does not mean that the actual buffer of characters (which is called string in common parlance) is only 4 bytes. Inside the 'std::string' class, there is a non static member pointer which is allocated dynamically to hold the input buffer. This can have as many elements as the system allows (C++ places no restriction on this length). But since the 'std::string' class only holds the pointer to this potentially infite length buffer, the sizeof(std::string) always remains the same as sizeof pointer on the given architecture which on your system is 4.
I know a lot of people had answered your question, but here are some points:
It's not the size of the string or the capacity of the string, this value represents the structural size of the class string, which you can see by its implementation (and it can change from implementation to implementation) that is a simple pointer;
As the sizeof(string) is the size of the class structure, you'll get the size of the only internal pointer, that in your case is 4 bytes (because you are in a 32-bit machine, this can change from platform to platform too);
This pointer inside the string class, points to a memory buffer where the class will hold the real string data, this memory buffer is reallocated as needed, it can increase/decrease as you append/delete/create more string text;
If you want to get the real size of the string, you need to call the size() method from the class which will check the memory buffer string size (which isn't the same as the memory buffer size).
I think your problem is your conception of sizeof, see more information here and here is some explanation on how it works.
Not at all. It means that the class's structure is that, it doesn't include the dynamic memory it can control. std::string will expand dynamically to meet any required size.
s.max_size() // will give the true maximum size
s.capacity() // will tell you how much it can hold before resizing again
s.size() // tells you how much it currently holds
The 4 you get from sizeof is likely a pointer of some kind to the larger structure. Although some optimizations on some platforms will use it as the actual string data until it grows larger than can fit.
No, it means that the sizeof the class string is 4.
It does not mean that a string can be contained in 4 bytes of memory. Not at all. But you have to difference between dynamic memory, used to contain the size characters a string can be made of, and the memory occupied by the address of the first of those characters
Try to see it like this:
contents --------> |h|e|l|l|o| |w|o|r|ld|\0|
sizeof 4 refers to the memory occupied by contents. What it contents? Just a pointer to (the address of ) the first character in the char array.
How many characters does a string can contain ? Ideally, a character per byte available in memory.
How many characters does a string actually have? Well, theres a member function called size() that will tell you just that
size_type size() const
See more on the SGI page !
A string object contains a pointer to a buffer on the heap that contains the actual string data. (It can also contain other implementation-specific meta-information, but yours apparently doesn't.) So you're getting the size of that pointer, not the size of the array it points to.
you can also use strings and can find out its length by string.length() function. look at the below code:
// Finding length of a string in C++
#include<iostream>
#include<string>
using namespace std;
int count(string);
int main()
{
string str;
cout << "Enter a string: ";
getline(cin,str);
cout << "\nString: " << str << endl;
cout << count(str) << endl;
return 0;
}
int count(string s){
if(s == "")
return 0;
if(s.length() == 1)
return 1;
else
return (s.length());
}
you can get the details from :
http://www.programmingtunes.com/finding-length-of-a-string-in-c/
size() of string gives the number of elements in the string whereas sizeof() function on a string gives three extra bits. strlen() of a character array gives the number of elements + 1 (because of null char delimiter) and keep in mind size of char is 1 byte. sizeof() on a char array gives the size assigned to the array
string str="hello";
char arr[x]="hello";
cout<<str.size()<<endl<<sizeof(str)<<endl;
cout<<strlen(arr)<<endl<<sizeof(arr)<<endl;
output is 5 8 5 x
Is '\0' set automatically if I provide an extra element for it, but left it in the initialization string?
Like:
char a[6] = {"Hello"}; // <- Is NUL set here automatically?
I´ve did one experiment with C and C++:`
C:
#include <stdio.h>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
printf("%s\n",NEWYEAR);
return 0;
}
Output:
Happy New Year!
C++:
#include <iostream>
int main()
{
char NEWYEAR[16] = {"Happy New Year!"};
std::cout << NEWYEAR << std::endl;
return 0;
}
Output:
Happy New Year!
The compilers did not threw an error or warning and the result is as desired. So it might seem to work correctly. But is that really true?
Is everything correct by doing so?
Is this maybe bad programming style?
Does this cause any issues?
It is more complex than that
char a[6] = "Hello";
will initialize the array of characters to Hello\0, because Hello has an implicit terminating zero.
char a[6] = "Hello\0";
would be valid in C, but invalid in C++ because the literal is 7 characters long, having both an implicit terminator and explicit embedded null character. C allows the literal to drop the implicit terminator. C11 6.7.9p14:
An array of character type may be initialized by a character string literal or UTF-8 string literal, optionally enclosed in braces. Successive bytes of the string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array.
char a[5] = "Hello";
would be valid C, resulting in a char array that does not contain a zero-terminated string. It is invalid in C++.
(emphasis mine). It means that the implicit terminating null is optionally added, if there is room in the array, but it does not need to.
And
char a[4] = "Hello";
in C would bring the literal Hell, because while it is a constraint violation in C (C11 6.7.9p2),
No initializer shall attempt to provide a value for an object not contained within the entity being initialized.
attempting to initialize more elements than there are items in a list usually just generates a warning in many compilers and is then often ignored by programmers. The paragraph 14 does not have an exception for anything other besides the implicit terminator.
And lastly
char a[7] = "Hello";
in both C and C++ would result in a character array of 7 elements containing the characters Hello\0\0, because in an array having an initializer, the elements not explicitly initialized by the initializer will be default-initialized as if initialized by literal 0. In this case the first 6 elements will be initialized explicitly and the 7th implicitly.
Given the possibility of silently truncating the terminator in C, it is better to just omit the array size and write
char a[] = "Hello";
This will declare a as array of 6 elements, just like char a[6] = "Hello";, but you cannot mistype the array size.
If there's space for the null-terminator then it will be added.
In C (but not C++) if the size of the array is the length of the string except the null-terminator, then the null-terminator will not be added. So e.g.
char a[5] = "Hello";
is valid, but there won't be a null-terminator in the array.
It's not valid to provide a smaller size than the string length.
This question already has answers here:
Struggling to get number of chars in char* [duplicate]
(2 answers)
What does sizeof(&array) return?
(4 answers)
Closed 9 years ago.
I tried to calculate the length of a character array in the following ways:
char *s="abcde";
int n=sizeof(s)/sizeof(s[0]);
cout<<n;
n comes out to be constant value 4, no matter how long the string is. Whereas had i declared the array as
char s[]="abc";
int n=sizeof(s)/sizeof(s[0]);
cout<<n;
The output still remains 4. I understand that in the second case, it includes the concluding character '\0', hence the output.
The only thing i didn't understand is why i get a constant output in first case.
With char *s you make a pointer s that points to some other memory. With char s[] = ... you make a an array of N characters.
Maybe it's easier if you look at it like this:
For the pointer version, char *s = "abcde", it will be something like
+---+ +-----------+
| s | ---> | "abcde\n" |
+---+ +-----------+
While for the case with the array, char s[] = "abc" it will be like
+---------+
| "abc\0" |
+---------+
This should make it easy to see why you can't use sizeof on the pointer, as it returns the size of the pointer and not what it points to. I have also added the string terminator that exists for all string literals, and this is why you get the size 4 for the array, it actually is four characters.
char *s is a pointer to either a char, or a sequence of char. On a 32bit architecture it will be 4 bytes wide, so sizeof(s) will be 4. A single character is (usually) 1 byte, so sizeof(s[0]) will be 1. Therefore, n will be 0.
When you use a char[] type the compiler treats it a a fixed length sequence, it's just working out how long the sequence will be for you, in your case it's 4 characters long. However, if you had:
char s[]="Hello, world";
int n=sizeof(s)/sizeof(s[0]);
Then n would be 13, as there the 12 character you entered, plus the null terminator at the end.
In this code snippet
char *s="abcde";
int n=sizeof(s)/sizeof(s[0]);
cout<<n;
s is a pointer. So sizeof( s ) is equal to the size of pointers in the system. In your system the size of a pointer is equal to 4. As the type of s[0] is char then its size equal to 1 and you get value 4.
In the second code snippet
char s[]="abc";
int n=sizeof(s)/sizeof(s[0]);
cout<<n;
s is an array. Its size is determined by the size of the initializer. As string literal "abc" has size equal to 4 because the terminating zero is also counted then the size of array s is 4. If you for example would write
char s[]="abcde";
int n=sizeof(s)/sizeof(s[0]);
cout<<n;
then the size of the string literal is equal to 6 and correspondingly the size of the array will be also equal to 6.
You could the same code rewrite the following way
char s[6]="abcde";
int n=sizeof(s)/sizeof(s[0]);
cout<<n;
If you write this code as
char s[10]="abcde";
int n=sizeof(s)/sizeof(s[0]);
cout<<n;
then the size of the array will be equal to 10 though the size of the string literal is equal to 6. All other elements of the array that have no initializer will be zero-initialized. That is the array would look as
[a][b][c][d][e]['\0']['\0']['\0']['\0']['\0']
In the first case, s is an object of type char*. sizeof(s) evaluates to the size of this "pointer to char" object, which is 4 (in your execution environment), not the length of the string that s points to (which strlen(s) evaluates to).
#include <cstdlib>
#include <iostream>
int main(int argc, char *argv[])
{
cout << "size of String " << sizeof( string );
system("PAUSE");
return EXIT_SUCCESS;
}
Output:
size of String = 4
Does that mean that, since sizeof(char) = 1 Byte (0 to 255), string can only hold 4 characters?
It isn't clear from your example what 'string' is. If you have:
#include <string>
using namespace std;
then string is std::string, and sizeof(std::string) gives you the size of the class instance and its data members, not the length of the string. To get that, use:
string s;
cout << s.size();
When string is defined as:
char *string;
sizeof(string) tells you the size of the pointer. 4 bytes (You're on a 32-bit machine.) You've allocated no memory yet to hold text. You want a 10-char string? string = malloc(10); Now string points to a 10-byte buffer you can put characters in.
sizeof(*string) will be 1. The size of what string is pointing to, a char.
If you instead did
char string[10];
sizeof(string) would be 10. It's a 10-char array.
sizeof(*string) would be 1 still.
It'd be worth looking up and understanding the __countof macro.
Update: oh, yeah, NOW include the headers :) 'string' is a class whose instances take up 4 bytes, that's all that means. Those 4 bytes could point to something far more useful, such as a memory area holding more than 4 characters.
You can do things like:
string s = "12345";
cout << "length of String " << s.length();
sizeof(char) is always 1 byte. A byte which we think is 8-bits need not be the case. There are architectures where a BYTE is 32-bits, 24-bits and so on. The sizeof applied to any other type is in multiples of sizeof(char) which is by definition 1.
The next important thing to note is that C++ has three character types: plain char, signed char and unsigned char. A plain char is either signed or unsigned. So it is wrong to assume that char can have only values from 0 to 255. This is true only when a char is 8-bits, and plain char is unsigned.
Having said, that assuming that 'string' is 'std::namespace', sizeof(string) == 4 means that the sizeof the 'std::string' class is 4 bytes. It occupies 4 times the number of bytes that a 'char' on that machine takes. Note that signed T, unsigned T always have the same size. It does not mean that the actual buffer of characters (which is called string in common parlance) is only 4 bytes. Inside the 'std::string' class, there is a non static member pointer which is allocated dynamically to hold the input buffer. This can have as many elements as the system allows (C++ places no restriction on this length). But since the 'std::string' class only holds the pointer to this potentially infite length buffer, the sizeof(std::string) always remains the same as sizeof pointer on the given architecture which on your system is 4.
I know a lot of people had answered your question, but here are some points:
It's not the size of the string or the capacity of the string, this value represents the structural size of the class string, which you can see by its implementation (and it can change from implementation to implementation) that is a simple pointer;
As the sizeof(string) is the size of the class structure, you'll get the size of the only internal pointer, that in your case is 4 bytes (because you are in a 32-bit machine, this can change from platform to platform too);
This pointer inside the string class, points to a memory buffer where the class will hold the real string data, this memory buffer is reallocated as needed, it can increase/decrease as you append/delete/create more string text;
If you want to get the real size of the string, you need to call the size() method from the class which will check the memory buffer string size (which isn't the same as the memory buffer size).
I think your problem is your conception of sizeof, see more information here and here is some explanation on how it works.
Not at all. It means that the class's structure is that, it doesn't include the dynamic memory it can control. std::string will expand dynamically to meet any required size.
s.max_size() // will give the true maximum size
s.capacity() // will tell you how much it can hold before resizing again
s.size() // tells you how much it currently holds
The 4 you get from sizeof is likely a pointer of some kind to the larger structure. Although some optimizations on some platforms will use it as the actual string data until it grows larger than can fit.
No, it means that the sizeof the class string is 4.
It does not mean that a string can be contained in 4 bytes of memory. Not at all. But you have to difference between dynamic memory, used to contain the size characters a string can be made of, and the memory occupied by the address of the first of those characters
Try to see it like this:
contents --------> |h|e|l|l|o| |w|o|r|ld|\0|
sizeof 4 refers to the memory occupied by contents. What it contents? Just a pointer to (the address of ) the first character in the char array.
How many characters does a string can contain ? Ideally, a character per byte available in memory.
How many characters does a string actually have? Well, theres a member function called size() that will tell you just that
size_type size() const
See more on the SGI page !
A string object contains a pointer to a buffer on the heap that contains the actual string data. (It can also contain other implementation-specific meta-information, but yours apparently doesn't.) So you're getting the size of that pointer, not the size of the array it points to.
you can also use strings and can find out its length by string.length() function. look at the below code:
// Finding length of a string in C++
#include<iostream>
#include<string>
using namespace std;
int count(string);
int main()
{
string str;
cout << "Enter a string: ";
getline(cin,str);
cout << "\nString: " << str << endl;
cout << count(str) << endl;
return 0;
}
int count(string s){
if(s == "")
return 0;
if(s.length() == 1)
return 1;
else
return (s.length());
}
you can get the details from :
http://www.programmingtunes.com/finding-length-of-a-string-in-c/
size() of string gives the number of elements in the string whereas sizeof() function on a string gives three extra bits. strlen() of a character array gives the number of elements + 1 (because of null char delimiter) and keep in mind size of char is 1 byte. sizeof() on a char array gives the size assigned to the array
string str="hello";
char arr[x]="hello";
cout<<str.size()<<endl<<sizeof(str)<<endl;
cout<<strlen(arr)<<endl<<sizeof(arr)<<endl;
output is 5 8 5 x
First off :
STRCAT :
Cplusplus - strcat
When clearly the definition says :
char * strcat ( char * destination, const char * source );
Why'd they use char str[80] in the example???
Shouldn't they have used a character pointer?
That is because arrays decay into pointers in C/C++. If you define char s[80] the value of s will be the address of the first character i.e &s[0]
array can also be used as pointer. what strcat needs is the pointer to a memory in which it copies the destination string. In this case str[80] will give you the memory that can hold 80 chars.
char str[80];
declares an array of 80 characters.
However, in C and C++, arrays are implicitly converted to pointers. When you pass an array to a function (such as strcat), it automatically "decays", forming a pointer to the first element of the array.
That's not the same as saying that arrays and pointers are the same thing. They aren't. For example, sizeof() yields different results on the above array, and a char*.
An array is, strictly speaking, a pointer to the beginning of a block of memory. So str is a char * that points to the beginning of 80 characters.
When you index into an array, say position 53, the following is equivalent: str[53] is the same as *(str + 53) as str is just a char * and adding 53 to a character pointer will return a pointer so to get the value inside you have to use an asterisk to dereference the pointer. In effect array notation just makes code more readable in certain circumstances.
Actually a great little trick with arrays of char is when you want to skip over some leading text when copying a string. E.g. let's say your array str[80] contains the string "1023: error in code!". And you want to display just the string without the number in front. In this case you could say printf( "%s", str + 6 ) and only "error in code!" would be printed.
char str[80];
Edit:
Opps, I rushed my answer. As dribeas says the statement declares an array and str can be implicitly converted into a pointer when it is used. For instance:
++str;
is an invalid operation while:
char* ptr;
++ptr;
isn't.