I test the length/size of char array, pointer and string as below code.
Why sizeof(pArray) is 8? I guess it is a pointer which should be 4.
Why sizeof(str) is 8 instead of 6 or 7?
Why sizeof("abcdef") is 7 instead of 6?
char array1[10] = {'a', 'b'};
char array[10] = "abcdef";
const char * pArray = "abcdef";
string str = "abcdef";
printf("array1:%d, array:%d, pArray:%d, str:%d,strsize:%d, strlen:%d, raw:%d\n", sizeof(array1), sizeof(array), sizeof(pArray), sizeof(str), str.size(), str.length(), sizeof("abcdef"));
Program output:
array1:10, array:10, pArray:8, str:8,strsize:6, strlen:6, raw:7
sizeof(array1) is 10 because you declared it with 10 elements.
sizeof(array) is also 10 for the same reason;
sizeof(pArray) is 8 maybe because you are in a 64 bit machine, so 8 bytes = 64 bit;
As the sizeof(str) is the size of the class structure, you'll get the size of the only internal pointer, that in your case is 8 bytes (because you are in a 64-bit machine, this can change from platform to platform too);
str.size() and str.length() returns the same - it's the length of the string itself;
sizeof("abcdef") is 7 because constant strings in C always get the implicit character '\0' at the end to terminate properly, so it is 1 more byte in your string (6 + 1 = 7);
The size of a pointer depends on the architecture. If compiled on a x64, it will be 8, on a 8/16 bit CPU, it may be 16 (less is very uncommon).
A string constant will always get an implicit "\0" at the end to terminate the string properly. Therefore be careful when assigning a string const to a fixed size array!
Related
#include <iostream>
int main(int argc, char* argv[])
{
int pt[4] = {'0','\0',0};
std::cout<<"size of pt: "<<sizeof(pt)<<std::endl;
std::cout<<"strlen of pt: "<<strlen((char*)pt)<<std::endl;
}
the result is:
size of pt: 16
strlen of pt: 1
and when I change int pt[4] = {'0','\0',0}; to int pt[4] = {'\0','0',0};
the result is
size of pt: 16
strlen of pt: 0
Why?
'0' is the "ASCII character 0" and has the value 0x30.
'\0' is the character representing the value 0 and has the value 0.
0 is just the value 0.
pt is an array of 4 integers, so its size is 4x the size of an integer on our machine (which is evidently 4), so you get 16.
Since pt is an array of integers whose first value is 0, which is 0x30, that value as an integer is 0x00000030. When you type cast pt to a character pointer, then it looks like a pointer to a character string whose first 3 values are zero. So the strlen is 0 (EDIT: because of the endianness of your particular architecture).
'0' is a character with the value 48, representing the printable and displayable digit.
'\0' and 0 are both the value 0, with the first having a character type and the second being an integer literal.
sizeof gives the number of bytes in an object or array. strlen counts the number of bytes from the start of an array of char to the first byte with the value 0, and does not include the terminating 0. In the case of your example, you have an array of 4 ints, with each int taking 4 bytes; 4*4=16.
I am adding values into the combo box as a string. Below is my code.
Platform Windows XP and I am using Microsoft Visual Studio 2003
language C++
error encountered -> "Run-Time Check Failure #2 - Stack around the variable 'buffer' was corrupted."
If I increase the size of the buffer to say 4 and above then I won't get this error.
My question is not related to how to fix that error, but I am wondering why I got this error if buffer size = 2.
According to my logic I have given buffer size = 2 as char[0] will store the valve of char[1] = null terminated character.
Now since char can store values from 0 to 255 , I thought this should be ok as my inserted values are from 1 to 63 and then from 183 to 200.
CComboBox m_select_combo;
const unsigned int max_num_of_values = 63;
m_select_combo.AddString( "ALL" );
for( unsigned int i = 1; i <= max_num_of_values ; ++i )
{
char buffer[2];
std::string prn_select_c = itoa( i, buffer, 10 );
m_select_combo.AddString( prn_select_c.c_str() );
}
const unsigned int max_num_of_high_sats = 202 ;
for( unsigned int i = 183; i <= max_num_of_high_sats ; ++i )
{
char buffer[2];
std::string prn_select_c = itoa( i, buffer, 10 );
m_select_combo.AddString( prn_select_c.c_str() );
}
Could you guys please give me an idea as to what I'm not understanding?
itoa() zero-terminates it's output, so when you call itoa(63, char[2], 10) it writes three characters 6, 3 and the terminating \0. But your buffer is only two characters long.
itoa() function is best avoided in favour of snprintf() or boost::lexical_cast<>().
You should read the documentation for itoa.
Consider the following loop:
for( unsigned int i = 183; i <= max_num_of_high_sats ; ++i )
{
char buffer[2];
std::string prn_select_c = itoa( i, buffer, 10 );
m_select_combo.AddString( prn_select_c.c_str() );
}
The first iteration converts the integer 183 to the 3 character string "183", plus a terminating null character. That's 4 bytes, which you are trying to cram into a two byte array. The docs tell you specifically to make sure your buffer is large enough to hold any value; in this case it should be at least the number of digits in max_num_of_high_sats long, plus one for the terminating null.
You might as well make it large enough to hold the maximum value you can store in an unsigned int, which would be 11 (eg. 10 digits for 4294967295 plus a terminating null).
the ito function is used to convert a int to a C sytle string based on the 3rd parameter base.
As a example, it just likes to print out the int 63 in printf. you need two ASII byte, one is used to storage CHAR 6, the other is used to storage CHAR 3. the 3rd should be NULL. So in your case the max int is three digital. you need 4 bytes in the string
You are converting an integer to ASCII, that is what itoa does. If you have a number like 183 that is four chars as a string, '1', '8', '3', '\0'.
Each character takes one byte, for example character '1' is the value 0x31 in ASCII.
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]
#define STR "test1"
Why does this take 6 bytes?
sizeof(STR) = 6
There is a trailing '\0' at the end.
a #define just does a text replacement before compiling.
#define STR "test1"
sizeof(STR);
is actually seen by the compiler as
sizeof("test1");
now why is that 6 and not 5? because there's a null terminator at the end of the string.
It has nothing to do with #define. A character array would be the same size:
const char str[] = { "test1" };
sizeof (str) == 6
The reason this string is 6 bytes long is that strings in C have a terminating NUL character to mark the end.
Strings in C are arrays of chars, with a null terminator i.e. they end with the \0. The common alternative is Pascal-style strings, where the string stores the array of chars without the null terminator, and stores the length of the string somewhere instead.
What the others said ... BUT
In C, preprocessing tokens take no space. It depends on how you use them
#define STR "test1"
char x[] = STR; /* 6 bytes */
char *y = STR; /* sizeof (char*) bytes (plus possibly 6 bytes) */
int ch = STR[3]; /* 1 byte (or sizeof (int), depending on how you look at it) */
if (ch == STR[1]) /* 1 byte (or sizeof (int) or no bytes or ...) */
printf("==>" STR "<==") /* 5 bytes ??? */
Why does this take 6 bytes?
Actually, it will take (6 bytes × the number of times you use it), because it's a preprocessor macro.
Try const char *STR = "test1" instead.
The latest C compiler has a feature to guess if the person writing the program is in a learning phase and give answers which make them search wider and deeper, and thus enrich their knowledge.
After programming for some time, depending of your learning, you might see the value go down to 5. ;-)
JK.. as someone else said, it symbolically nothing at the end which ironically takes a byte.
I don't use correctly the format specifiers in C. A few lines of code:
int main()
{
char dest[]="stack";
unsigned short val = 500;
char c = 'a';
char* final = (char*) malloc(strlen(dest) + 6);
snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest);
printf("%s\n", final);
return 0;
}
What I want is to copy at
final [0] = a random char
final [1] = a random char
final [2] and final [3] = the short array
final [4] = another char ....
My problem is that i want to copy the two bytes of the short int to 2 bytes of the final array.
thanks.
I'm confused - the problem is that you are saying strlen(dest)+6 which limits the length of the final string to 10 chars (plus a null terminator). If you say strlen(dest)+8 then there will be enough space for the full string.
Update
Even though a short may only be 2 bytes in size, when it is printed as a string each character will take up a byte. So that means it can require up to 5 bytes of space to write a short to a string, if you are writing a number above 10000.
Now, if you write the short to a string as a hexadecimal number using the %x format specifier, it will take up no more than 2 bytes.
You need to allocate space for 13 characters - not 11. Don't forget the terminating NULL.
When formatted the number (500) takes up three spaces, not one. So your snsprintf should give the final length as strlen(dest)+5+3. Then also fix your malloc call to adjust. If you want to compute the strlen of the number, do that with a call like this strlen(itoa(val)). Also, cant forget the NULL at the end of dest, but I think strlen takes this into account, but I'm not for sure.
Simple answer is you only allocated enough space for the strlen(dest) + 6 characters when in all reality it looks like you're going to have 8 extra characters... since you have 2 chars + 3 chars in your number + 2 chars after + dest (5 chars) = 13 char when you allocated 11 chars.
Unsigned shorts can take up to 5 characters, right? (0 - 65535)
Seems like you'd need to allocate 5 characters for your unsigned short to cover all of the values.
Which would point to using this:
char* final = (char*) malloc(strlen(dest) + 10);
You lose one byte because you think the short variable takes 2 byte. But it takes three: one for each digit character ('5', '0', '0'). Also you need a '\0' terminator (+1 byte).
==> You need strlen(dest) + 8
Use 8 instead of 6 on:
char* final = (char*) malloc(strlen(dest) + 6);
and
snprintf(final, strlen(dest)+6, "%c%c%hd%c%c%s", c, c, val, c, c, dest);
Seems like the primary misunderstanding is that a "2-byte" short can't be represented on-screen as 2 1-byte characters.
First, leave enough room:
char* final = (char*) malloc(strlen(dest) + 9);
The entire range of possible values for a 1-byte character are not printable. If you want to display this on screen and be readable, you'll have to encode the 2-byte short as 4 hex bytes, such as:
## as hex, 4 characters
snprintf(final, sizeof(final), "%c%c%4x%c%c%s", c, c, val, c, c, dest);
If you are writing this to a file, that's OK, and you might try the following:
## print raw bytes, upper byte, then lower byte.
snprintf(final, sizeof(final), "%c%c%c%c%c%c%s", c, c, ((val<<8)&0xFF), ((val>>8)&0xFF), c, c, dest);
But that won't make sense to a human looking at it, and is sensitive to endianness. I'd strongly recommend against it.