Memory allocation of character array in C++ - c++

#include<iostream>
using namespace std;
int main()
{
cout<<"Enter\n";
char ch[0];
cin>>ch;
cout<<sizeof ch;
cout<<sizeof &ch;
cout<<"\n You entered \n"<<ch<<"\n";
return 0;
}
I use g++ compiler to compile the C++ program. What is the difference in memory allocation of char ch and char ch[0]. ch can accept one character but ch[0] can accept many character(I put in qqqqqqqq). Why? Also why does sizeof ch return 0 whereas sizeof &ch gives 4, yet ch accepts more than four characters?

Let's take this line by line:
char ch[0];
declares a zero-length array of characters. As mentioned in the comments, C++ standards don't actually allow this, but g++ might.
cin >> ch;
puts whatever's read in into the zero-length array. Since cin doesn't know the length of your array (it decays into a char * when it gets passed to the stream), it writes as much as it feels, which means it can store more than zero characters.
cout << sizeof ch;
outputs the size (ie. total space used in bytes) of the array, which is zero, as mentioned earlier.
cout << sizeof &ch;
outputs the size of the address of the array, which is 4 bytes on your architecture, since it's just a pointer.
cout << "You entered\n" << ch << "\n";
outputs whatever was stored into the array, which isn't well-defined, because, as I mentioned, zero-length arrays are not standard C++. Further, since cout just writes memory until it encounters a null byte (\0), it writes as much as you stored, since again, cout doesn't care whether you delcared ch with size 0 or size 413.

What is the difference in memory allocation of char ch and char ch[0].
The difference is in how much the compiler is going to protected you from yourself. An array is just a sequential block of memory, C++ has not array out of bounds exceptions, and doesn't check array bounds before writing. By using
char ch[0];
you have told the C++ compiler you will be responsible for bounds checking. This is a buffer overflow (remember those). When you assign something like 'qqqq' to ch[0] you have overwritten some other piece of memory that belongs to some other variable, function or program. Try running the program below if you need a better understanding.
// Note that I'm setting arr[10], which in Java (or any other modern language) would
// be an array out of bound exception
// I haven't run this program, but you're most likely to get 'a' printed
// to standard out
char arr[10], achar;
arr[10] = 'a';
cout << achar;

Related

C++ calculate size of array of strings from file [duplicate]

#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

Pointer of a character in C++

Going by the books, the first cout line should print me the address of the location where the char variable b is stored, which seems to be the case for the int variable a too. But the first cout statement prints out an odd 'dh^#' while the second statement correctly prints a hex value '
ox23fd68'. Why is this happening?
#include<iostream>
using namespace std;
int main()
{
char b='d';
int a=10;
char *c=new char[10];
c=&b;
int *e=&a;
cout<<"c: "<<c<<endl;
cout<<"e: "<<e;
}
There is a non-member overload operator<<(std::basic_ostream) for the const char* type, that doesn't write the address, but rather the (presumed) C-style string1). In your case, since you have assigned the address of a single character, there is no NUL terminator, and thus no valid C-style string. The code exhibits undefined behavior.
The behavior for int* is different, as there is no special handling for pointers to int, and the statement writes the address to the stream, as expected.
If you want to get the address of the character instead, use a static_cast:
std::cout << static_cast<void*>( c ) << std::endl;
1) A C-style string is a sequence of characters, terminated by a NUL character ('\0').
Actually this program has problem. There is a memory leak.
char *c=new char[10];
c=&b;
This allocates 10 characters on heap, but then the pointer to heap is overwritten with the address of the variable b.
When a char* is written to cout with operator<< then it is considered as a null terminated C-string. As the address of b was initialized to a single character containing d op<< continues to search on the stack finding the first null character. It seems the it was found after a few characters, so dh^# is written (the d is the value of variable b the rest is just some random characters found on the stack before the 1st \0 char).
If you want to get the address try to use static_cast<void*>(c).
My example:
int main() {
char *c;
char b = 'd';
c = &b;
cout << c << ", " << static_cast<void*>(c) << endl;
}
An the output:
dÌÿÿ, 0xffffcc07
See the strange characters after 'd'.
I hope this could help a bit!

C++ - Converting a char to wchar_t. Getting a segfault

I'm trying to write small program that reads in a character from an istream and converts it to a wchar_t. I'm getting a segfault. Here's my code
#include <iostream>
using namespace std;
wchar_t read(istream &stream) {
char *c;
stream.read(c, sizeof(*c));
cout << *c << endl;
wchar_t retChar = static_cast<wchar_t>(*c);
return retChar;
}
int main() {
cout << "Write something" << endl;
read(cin);
}
My logic here is:
Create an array of chars because read only takes arrays of chars.
Read in bytes equal to the size of a character. i.e. read a character and store it in the array c.
Create a wchar_t and cast that character *c into a wchar_t.
return wchar_t
Since I'm getting a segfault, there's obviously something wrong here. I can't see it though. Any help would be appreciated.
Thanks SO
Stepping through the code to give OP a look at what's going on and why it won't work. Then we'll take a look at a method to do what they want that is as close as possible to their intent. Then a hint on how to do this a bit better in the C++ world.
wchar_t read(istream &stream) {
char *c;
Declares a pointer c and doesn't point it at anything. c is an uninitialized variable. Think of it like being invited to Steve's house for a party, but no one told you where he lived. Odds are very good that where ever you go, it won't be Steve's house.
stream.read(c, sizeof(*c));
sizeof(*c) will return the size of one character. Probably 8 bits and 1 byte, but c still hasn't been pointed at anything so this is Undefined Behaviour. There is no telling what the program will do, but most likely it reads one byte into some unknown space in memory. Maybe this causes a crash because you can't write there. Maybe it writes over something that it is allowed to write over and screws up something else.
cout << *c << endl;
Tries to print out c. If the program survived the read above, odds are good it will survive this as well, but this is also Undefined Behaviour.
wchar_t retChar = static_cast<wchar_t>(*c);
This will literally stuff one character's worth of data into a wide character. It will not convert it according to locale or any other character encoding. char is a numeric code that has been defined to be interpreted as a character. A cast will stupidly put the character value, say 'A' and ASCII encoding into retChar. retChar now equals 65. 65 could mean anything depending on the encoding used by wchar_t. It might still mean 'A', but sorry Ayn Rand, this is one case where A may well not be A.
return retChar;
}
To do what OP was trying to do (and ignoring that there are better ways to do this for the time being):
#include <iostream>
using namespace std;
wchar_t read(istream &stream) {
char c[2];
Allocates an array of characters. Why? because the easiest way I know of is to do the conversion on a string.
stream.read(c, sizeof(c[0]));
c is now an array which decays to a pointer. We only want to read one char, so sizeof(c[0]) gets the size of the first element in the array.
c[1] = '\0';
cout << c << endl;
Null terminate and print.
wchar_t retChar[2];
Again, an array.
mbstowcs(retChar, c, 1);
convert one character from char to wide char using whatever locale has been set. Read more on locales here: http://en.cppreference.com/w/cpp/locale/setlocale
And documentation on mbstowcs: http://en.cppreference.com/w/cpp/string/multibyte/mbstowcs
return retChar[0];
}
Put all together with a quick tester:
#include <iostream>
#include <cstdlib>
wchar_t read(std::istream &stream)
{
char c[2];
stream.read(c, sizeof(c[0]));
c[1] = '\0';
std::cout << c << std::endl;
wchar_t retChar[2];
mbstowcs(retChar, c, 1);
return retChar[0];
}
int main()
{
std::wcout << read(std::cin) << std::endl;
}
This is simple, but ugly in the C++ world where you should stick to strings where possible. In that case look into std::wstring_convert.

c++ sizeof( string )

#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

C++ char array with stdin

I am trying to get the size of an array populated by stdin:
char *myArray;
cin >> myArray
cout << sizeof(myArray);
This returns 4 when I enter a string greater with a length greater than 4 e.g. "40905898"
Where am i going wrong?
sizeof operator statically evaluates to the size of the thing you are passing to it. A char* is a pointer which, depending on the machine architecture has a specific size (4 bytes on 32 bit systems and 8 bytes on 64 bit machines). To accomplish what you are trying to do, I suggest you use the string type which you can use by adding #include <string> along with using namespace std; to your source file.
string line;
cin >> line;
cout << line.length() << endl;
It's less error prone and easier to use.
By the way, the thing you've tried to do is really dangerous. In fact, when you use cin >> myArray, you should have already allocated some memory for myArray which you haven't done. This will cause memory corruption which might crash your program and possibly put it to buffer overrun attacks.
A simple array in C++ has no idea about its size. You can use sizeof only if the array is statically allocated and you are using sizeof on the array itself, not another pointer to it, for example this won't work as you might expect:
int x[5];
int *a = &x[0];
// a[i] is now the same as x[i] but:
cout << sizeof(x) << endl; // prints 20, assuming int is 32 bits long
cout << sizeof(a) << endl; // prints 4, assuming a pointer is 32 bits long
Note that the total size of the array is printed on the first line, not the element count. You can use sizeof(x)/sizeof(*x) to find out element count in static arrays. This thing is not possible for dynamically allocated arrays using new. In fact C++ arrays are very error prone and you should take extreme care when working with them and you'd better use vector and string in most cases instead.
sizeof(pointer) will always return 4. You want to use strlen().
Edit: IIRC, sizeof is evaluated at compile time, it only cares about the type, not the content.
This is because myArray is a pointer that occupies 4 bytes. If you want to get the length of your string, use strlen or something similar.
It's because you are using sizeof() on a pointer, which is 4 bytes on your 32-bit computer:
printf("Pointer size: %d\n", sizeof(void*));
If your array is a null-terminated string (the last element being a zero-byte, or '\0'), then you can use
strlen(myArray)
to get the number of elements (minus one). E.g.:
myArray = "Hello, world!";
printf("Number of characters: %d\n", strlen(myArray));
You could also use a statically allocated array, like this:
char array[128];
printf("sizeof(array) = %d\n", sizeof(array));
// prints 128
As others said, myArray is a pointer.
But why wouldn't you use std::string? You won't need to do the buffer allocation yourself, which you do wrongly in your example (pointer myArray points to nothing)
std::string myValue;
std::cin >> myValue;
std::cout << myValue.length();
If needed, you can get to a pointer representation of the string by using string::c_str().
As others said sizeof returns the size of the object passed to it, in the case of a pointer it's the size of the pointer. sizeof does not follow the pointer to see what size the object it points to is (how can it know it could point to one char or to an array there's not good way to know).
Additionally when you read from cin you have to allocate some space into which the data must be read, cin will not allocate space for you. You can allocate space either on the stack or the heap:
char stack_line[1024]; // This will overflow if more than 1024 chars are needed
char heap_line* = new char[1024]; // ditto
The thing to note here is that sizeof(stack_line) == 1024 while sizeof(heap_line) == 4 [on 32 bit machines] so you must be careful when using the sizeof operator.
In practice it's better to use an std::string which knows how to allocate the space itself.
You seem to have lots of problems here:
myArray is not initialised - where is the input going to live?
You usually use: cin >> myArray; (Note the direction of the chevrons and the semi-colon)
sizeof(myArray) will always return the same value (4 on your platform)
Try this version instead:
char* myArray= new char[50];
cin >> myArray;
cout << myArray;
cout << strlen(myArray);
Its not without its own problems (I should have deleted myArray), so you should try the answers here that use string myArray
well if you were going to use sizeof(myArray), you should've done sizeof(*myArray); because with pointers, no star is the address not the value.
Like this:
char *myArray;
cin >> *myArray;
cout << *myArray;