Though string is dynamic so it will not have any definite size so when i get s[1] before s[0] how C++ will calculate its offset address.
For example int a[2]
0000:1000 a[0]
0000:1004 a[1]
Program:
#include<iostream>
#include<vector>
using namespace std;
int main()
{
string s[2];
cin>>s[1];
cout<<s[1]<<endl;
cin>>s[0];
cout<<s[0]<<endl;
}
An array of strings is an array of string objects, which are of fixed size and effectively contain pointers elsewhere where the strings actually reside.
std::string does not in its memory layout actually contain its characters. It simply contains a pointer to a dynamically allocated memory and keeps track of its size. Just like std::vector doesn't actually store its elements inside its members. Instead, it has a pointer to the actual elements situated "on the heap". S
So regardless of the number of characters a string has, its size (meaning sizeof (std::string) )is a compile time constant.
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
In C++, what's the difference between this:
char example[10];
and this:
char* example = new char[10];
in both cases, I'm not initializing the content of the arrays, but just wanting to get 10-bytes in memory allocated to the character array. In both cases, I intend to then use sprintf() to assign a string value to them with no intermediate step.
This:
char example[10];
Declares example as an array of char containing 10 elements. If declared at file scope, this array will typically reside in the data segment, while if it is declared at block scope it will typically reside on the stack.
In contrast, this:
char* example = new char[10];
Declares example as a pointer to char, and initializes it with a pointer to dynamically allocated memory which points to the first member of a 10 member array of char. This dynamically allocated memory typically resides on the heap.
Note also that new is specific to C++.
char example[10];
example is an array of 10 chars. Depending on context, it has automatic or static storage. The size can only be compile time constant. The array is destroyed and deallocated automatically.
char* example = new char[10];
example is a pointer. It is not an array. It points to first element of an array in dynamic storage. The size of dynamic array can be determined at runtime. The array is not destroyed and deallocated automatically. If not deallocated, the memory will leak.
Dynamic allocation is generally slower than static or automatic. On the other hand, the amount of memory available for automatic storage is typically very limited.
Bare owning pointers should be avoided. Best practice is to use a smart pointer or a RAII container such as std::vector when dynamic array is needed.
The main difference is that, in your first example you are have to already know at declare this char array his size, but in your second example, you are declare char array with pointer, which points on some value. That means you can only declare some char pointer without knowing the size of the char array. It is very usefull for programs, where the user has to write his nickname as input, maximal lenght of nickname can be 10 characters, but it can be less then 10 characters, that means you have to use pointers for dynamic allocating memory so as not to use too much unused memory.
For example:
int main()
{
char nm[10]; //Create char array, where you will save an input
char* nickname; //Declare pointer
std::cout << "Nickname: " << std::endl;
fflush(stdin);
gets(nm); //Save input
// Here we go find the size of used memory in char array nm
int size_of_nm = 0;
for (char i : nnnn)
{
if (i == '\0') //If char i is equal to zero character, we find the size of used
{ //memory in char array nm
break;
}
else //If i is not equal to zero character, we do not find the size of used
{ //memory in char array nm and loop will continue
size_of_nm++; //Size counter plus one
}
}
nickname = new char[size_of_nm + 1]; //Create new pointer on char array and set the
//size of used memory in char array
//plus one, because the char array is always
//ending with zero character
}
But I recommend using a strings. It is more safer, because you dont have to know the size of used memory, memory of string is allocated automatically.
I am recreating the string class using char arrays. My problem is, when I allocate memory for a larger array, it generates an array that is completely the wrong size.
For example:
int allocated = 4;
char * reservedString = new char[allocated];
cout << strlen(reservedString);
Instead of creating a character array of size 4, reservedString points to a character array with 14 spots containing random characters.
This is what the debug shows me. Reserved string is now the wrong size with a bunch of random characters in it. When I try to use strcpy or strcpy_s it is writing memory out of bounds because the new array sizes are wrong.
How can I create a char array with an unknown length, which is provided by a variable, that is right size.
I can not use the std::string class or std::vector.
When you are creating an object with the new operator, your data remains not initialized. The code you provide is basically an array of bytes.
The documentation about strlen says:
computes the length of the string str up to, but not including the terminating null character.
There is no null terminator here.
You should do:
int allocated = 4;
char * reservedString = new char[allocated]();
This will initialize your array and set all the elements to \0
strlen expects a null-terminated string, which means a string that ends in a null character (\0). You're passing to it a pointer pointing to newly allocated memory, which contains uninitialized values and reading it causes undefined behavior. So when strlen searches for a null character in order to determine the length of the string, stuff is going to go wrong.
You cannot determine the size of an array given only a pointer to it unless you know it's going to be terminated by a null character or something similar. So either properly initialize the array with a null-terminated string or keep track of the length yourself.
Given an array of strings, i need to find out the number of strings in it.
I followed this
but this doesn't work if i am passing this into a function.
here's the code i tried
#include<string>
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int f1(char* input1[])
{
string s="";
cout<<sizeof(input1)<<endl; //print 4
cout<<sizeof(char*)<<endl; //print 4
int l=sizeof(input1) / sizeof(char*);
//giving l=1 here but should be 8
}
int main()
{
char *str2[]={"baba","sf","dfvf","fbfebgergrg","afvdfvfv","we","kkhhff","L"};
int l=sizeof(str2) / sizeof(char*);
cout<<l<<endl; //print 8
cout<<sizeof(str2)<<endl; //print 32
cout<<sizeof(char*)<<endl; //print 4
f1(str2);
}
sizeof(char*) gives you the size of the char* pointer (which is 4 on your system).
sizeof(str2) is giving you the size of the array str2. There are 8 elements, each one is a pointer type. So the total size on your system is 8 x 4 = 32.
To get the length of a string, use strlen.
Do consider std::vector<std::string>> as an alternative in C++.
You can not know the length of an array if you only have a pointer to it. And you do have only a pointer because you cannot pass arrays by value. Arrays passed to a function will automatically decay to a pointer and the argument type char* foo[] is equivalent to char** foo. size_of doesn't help because it will only tell the size of the pointer itself.
Pass the length as an argument to f1. Or better yet, use std::vector or std::array.
i cannot modify the given function prototype
Well, that's unfortunate. Then you must resort to some trickery. The simplest workaround is to store the length in a global variable instead of a function parameter.
Another possibility is a terminating value For example, always end the array with nullptr and never allow other elements to have that value. In the same way as c-strings are terminated with null character. Then you can stop iterating the array when come across nullptr. But I assume you cannot modify the array either.
can we declare size to a pointer
#include<iostream>
#include<cstring>
using namespace std;
int main()
{
char (*ptr)=new char[3];
strcpy(ptr,"ert");
cout<<ptr<<endl;
return 0;
}
what is the meaning of this line char *ptr=new char[3] if it allocates size to ptr.since i have given the size as 3 and the string as "ert"it has to show error since the string length is too long but it doesn't .can we allocate size to pointers if so how?
You need 4 characters:
char *ptr=new char[4];
strcpy(ptr,"ert");
One extra space for the nul terminator:
|e|r|t|\0|
It's not the size of the pointer that you've declared, but the size of the character array that the pointer points to.
strcpy() does not know the length of the array that the pointer points to - it just knows it's got a pointer to the first byte it can copy into, and trusts that you know there's enough room for the copy to be made. Thus it's very fast, but it's also rather dangerous and should be used only when you're sure the destination is large enough.
strncpy() is worth looking into for some extra safety, but you still have to know that the target pointer points to something large enough for the size you specify (it protects more against the size of the source than the size of the target).
The lesson to learn here is that C and C++ won't give you any help - the compiler trusts you to get your buffer sizes right, and won't do any checking on your behalf either at compile time or runtime. This allows programs to run extremely fast (no runtime checking) but also requires the programmer to be a lot more careful. If you're writing in C++ which your tags suggest, for normal string handling you should definitely be using the std::string class unless you have a specific reason to need C-style string handling. You may well have such a reason from time to time, but don't do it unless you have to.
This statement
char (*ptr)=new char[3];
at first allocates in the heap unnamed character array with 3 elements and then the address of the first element of the array is assigned to pointer ptr.
The size of the pointer will not be changed whether you initialize it as in the statement above or the following way
char (*ptr)=new char;
that is sizeof( ptr ) will be the same and equal usually either to 4 or 8 bytes depending on the environment where the program will be compiled.
C++ does not check bounds of arrays. So in this statement
strcpy(ptr,"ert");
you have undefined behaviour of the program because string literal "ert" has four elements including the terminating zero.