How many bytes does a #define string (string literal) take? - c++

#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.

Related

Size of char pointer and string

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!

how values are stored in char

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.

Different answers from strlen and sizeof for Pointer & Array based init of String [duplicate]

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]

format specifier for short integer

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.

sprintf_s problem

I have a funny problem using this function.
I use it as follow:
int nSeq = 1;
char cBuf[8];
int j = sprintf_s(cBuf, sizeof(cBuf), "%08d", nSeq);
And every time I get an exception. The exception is buffer to small.
When I changed the second field in the function to sizeof(cBuf) + 1.
Why do I need to add one if I only want to copy 8 bytes and I have an array that contains 8 bytes?
Your buffer contains 8 places. Your string contains 8 characters and a null character to close it.
Your string will require terminating '\0' and 8 bytes of data(00000001) due to %08d.
So you have to size as 9.
All sprintf functions add a null to terminate a string. So in effect your string is 9 characters long. 8 bytes of text and the ending zero