i wonder about int array in c affect to memory.
for example we opened char array char array[10];
it wont open 10 it'll open 11 because of '\0'
is there same situation on int array?
when we declare int abc[10]; will it open array that is 10 int size or 11 like char?
Thanks...
You are wrong with regards to char array[10]. This will not declare an array of 11 elements, only 10, including the terminating '\0'. This means that if you put a string of ten characters in the array, it will overflow.
some_type name[10] will always declare an array of 10 elements, never more, never less.
Any array declaration will have x number of elements
type array[x]
not x+1.
not even the char one.
read here more about arrays:
http://www.cplusplus.com/doc/tutorial/arrays/
I think declaring char array[10] allocates exactly 10 bytes of space, it is your job to manage memory with '\0' if you see fit.
int abc[10] creates an array of 10 ints, with subscripts 0 through 9. Changing the type (e.g., to char abc[10] doesn't change the number of items in the array.
With an array of char, the NUL terminator is considered part of the string, so if you provide an initializer and specify a size, the size must be at least as large as the size of the string including the NUL terminator. If you don't specify the size, the size will be the length of the string including the NUL terminator.
char a[] = "A string"; // sizeof(a)==9
Note, however, that C is slightly different in this respect -- in C you can specify an initializer and a size that does not include space for the NUL terminator, and it'll still compile.
char a[9] = "A string"; // allowed in either C or C++
char a[8] = "A string"; // allowed in C, but not C++.
I'm not sure what you mean by "opened" an array. If you declare:
char array[10];
you define an array of ten char. If you declare:
int array[10];
you define an array of ten int. Both uninitialized unless defined
with static lifetime.
The appended '\0' only affects string literals and initialization
strings.
for example we opened char array char array[10]; it wont open 10 it ll open 11 because of '\0'
Wrong. In C, you are expected to take care of your terminating \0's in strings - the compiler won't do any favour for you. If you declare a char[10], you get exactly 10 chars, and the same is true for ints and all other types.
A char array[10] will create an array of 10 elements. I think you are a bit confused because in c typically you have to create an array of size 11 to store a word of size 10, because you need to have one extra element for the '\0' char in the end. But still you have to declare the array to be of size 11, not 10. The compiler will not do that for you.
I think you are somewhat confused about initializing an array of char in C++. char array[10] will have size 10, not size 11, however, char array[] = "1234567890"; will have size 11 because the initialization knows that your char array needs to end with a newline character.
Related
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.
For the following piece of code:
char a[] = "Apple";
char *s[] = {"Apple"};
printf("%d %d\n", sizeof(a), sizeof(s[0]));
The output is:
6 4
Can someone tell me why sizeof() is giving different outputs?
EDIT: I did intend to type sizeof() originally, but typed strlen() instead. I apologize for the same. I have edited the statement now.
sizeof(a) is the size of the array, which contains the terminator as well as the 5 printable characters.
strlen(s[0]) gives the length of the string, excluding the terminator, since that is what strlen is specified to do.
UPDATE: sizeof(s[0]) is the size of a pointer. There's no way to determine the size of an array given just a pointer to it.
sizeof gives you the number of chars allocated to a while strlen gives you the length of useable string in a.
the \0 counts as part of the size in memory of the string, but the length of the string itself, given by strlen(), is only given by the characters before the \0 is encountered.
A character array declared like this:
char a[] = "Apple";
has, according to the language specification, a null-terminator. Therefore, the length of the array is 6. There are 5 characters, and then the null terminator.
On the other hand, strlen() returns the number of characters that precede the null terminator. Which is 5.
The sizeof operator yields the size (in bytes) of its operand.
In this statement
char a[] = "Apple";
array a is initialized by characters of string literal "Apple" that includes the terminating zero.
In fact this record is equivalent to
char a[] = { 'A', 'p', 'p', 'l', 'e', '\0'; };
So the size in bytes of a is equal to 6.
Standard C function strlen counts symbols in a string until it encounters the terminating zero. So
strlen( a )
will return 5 that is the number of characters in the array that are before the terminating zero.
Take into account that you could write for example
char a[100] = "Apple";
In this case sizeof( a ) will yield 100 because you explicitly specified the number of bytes that the array will occupy. However it was initialized only with 6 characters of the string literal. So how to find how many actual data are in the character array? For this purpose function strlen was introduced that to distinguish the size of a character array and the number of actual data in the character array.
Because in C there is no string type. String is a character array which is NULL terminated. strlen() counts the characters until the NULL character, whereas sizeof() actually returns the amount of memory used up by the charater array.
a is an array of chars, which contains 6 elements, hence sizeof returns 6 (the length of the string including zero termination).
s is an array of pointers to char. The pointer size is 4 bytes. sizeof(s[0]) returns the size of the first element, which is pointer, i.e. its size is 4.
When you define:
char a[] = "Apple";
It means an array of characters, which equals to the following definition:
char a[] = {'A', 'p', 'p', 'l', 'e', '\0'}; // '\0' is the string termination character which equals to 0
Since char type size is 1, the sizeof(a) returns 6 which is the size of the whole array.
Nevertheless, when you define:
char *s[] = {"Apple"};
It means an array of char pointer. Hence sizeof(s[0]) return the size of its first element which
equals to sizeof(char*).
For a 32-bit platform, sizeof(char*) = 4. If you do it on an 64-bit platform, 8 is the expected value.
What is the difference between
char (CharBuff[50])[10];
and
char CharBuff[10][50];
My requirement is to have 10 character buffers, each of length 50 max (including null terminating character)
And, I would like to access the buffers as CharBuff[0], CharBuff[1] and so on.
char (CharBuff[50])[10];
declares CharBuff as a 50-element array of 10-element arrays of char. The parentheses are superfluous in this case.
char CharBuff[10][50];
declares CharBuff as a 10-element array of 50-element arrays of char.
Given that you want 10 strings of up to 50 characters, you would use the second form; the type of each CharBuff[i] will be "50-element array of char".
If you really wanted to create a separate type definition for a 50-element array of char, you could do something like
typedef char Str[50];
...
Str CharBuff[10];
Now CharBuff is a 10-element array of Str, which is a 50-element array of char.
Normally, I would not create a separate typedef like this unless I wanted to make Str opaque; that is, I don't want to expose the details of its implementation to whomever's using it. In addition to the typedef, I'd also supply an API for allocating, assigning, copying, formatting, and displaying objects of type Str.
Put another way, if the person using the Str type has to be aware that it's a 50-element array of char in order to use it properly, then it's better to just make them use a 50-element array of char.
The other answers here which say they're the same are wrong! Both are NOT the same arrays and their sizes are very different. Here's a snippet to show that:
char i[50][10];
std::cout << sizeof(i[1]) << '\n';
char (j[10])[50];
std::cout << sizeof(j[1]) << '\n';
10
50
You can see the live example here.
i is a 50-element array with each element being a 10-element array of characters, while j is a 10-element array with each element being a 50-element array of characters. Although the total sizes of both would be the same, the size of an element at each level would be different. If you assume they're the same, it would lead to undefined behaviour
i[25][5] // OK
j[25][5] // accessing j beyond index 9 is undefined behaviour!
This shows that the parenthesis have no significance in a non-pointer, non-reference array declaration i.e. char (j[10])[50] is just confusing notation for char j[10][50].
My requirement is to have 10 character buffers, each of length 50 max
Then you should declare your array as char CharBuff[10][50].
Nobody ever uses the former, always use the latter form:
char CharBuff[10][50];
Latter syntax will be proficient and less confusing as per you requirement of 10 rows (char buffers) having length of 50 each.
Go for the last one as it clearly states what you are allocating.
However, since the question is tagged with c++ too, I would advise using std::vector and std::string as it follows:
std::vector<std::string> CharBuff(10, std::string(50, '\0'));
The big problem that i see here is confusing syntax. When you use parenthesis they already have known roles in c and c++ syntax such as type conversions, pointers to functions(which looks a bit like what you wrote). What you are using them for add's a new meaning which makes code more obfuscated and ignores the fact that c and c++ have a great and intuitive way, for anybody that used matrices at least once, to express 2d arrays. So, for a clean and not confusing syntax use the latter version:
char CharBuff[10][50];
You are looking for 10 arrays of 50 chars each.
To declare a single buffer of 50 bytes, you would use
char CharBuff[50];
But you want to have 10 buffers, so just tack that on to before[50], e.g.:
char CharBuff[10][50];
Now CharBuff[0] will address the first fifty-byte buffer, CharBuff[1] will get the second, and so on.
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).
I would appreciate for some C++ expertize advice on this please. I have a Char array
<unsigned char ch1[100];>
data (ASCII code) gets filled in this ( max 6 or 8 array spaces and rest is empty). I want to process valid bits in the array only either converting them to Hex or again Char array. I tried
<memcpy (ch1,ch2,sizeof(ch1))>
but all garbage values are also copied..... :(
<strcpy gives me an error>
also number of bytes copied are dynamic ( 1 time :- 4; 2 time :- 6.....)
Do you know how many valid bytes do you have in your array? If yes, you can pass that number in as the 3rd argument of memcpy.
Otherwise you can zero-initialize the array and use strcpy which will stop on the first zero:
char ch1[100];
// zero out the array so we'll know where to stop copying
memset(ch1, 0, sizeof(ch1));
... data gets filled here ....
strcpy (ch2, ch1);
// zero out array again so we'll catch the next characters that come in
memset(ch1, 0, sizeof(ch1));
... life goes on ...
So only copy the chars that are actually initialized. You as a programmer are responsible for tracking what's initialized and what's not.