Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm really confused about this because personally, I come from a java background, and recently began c++. So, I learnt all the basic stuff, like, printing stuff out to the screen and whatnot, and now, I learnt POINTERS. So, the person on youtube (The Cherno's C++ Pointer tutorial This was not the video where he declared the const char*, just the pointer tutorial that I followed.) I've been following was using this following statement to declare what I know as a 'string'.
const char* str = "random text here";
But, how is a char* converted into a string, and its even using the double quotation marks like a string! Also, what does a constant have to do with any of this? If I remove the const from my code it gives me an error. But, I understand what a pointer is. It is a variable that holds the memory address of another variable, so if one was to access that variable directly, they would just have to do *ptrVarName and dereferenced it. But how can a string "like this one" be a memory address?
Wouldn't I have to do something like this?
char[] str = "string here";
and THEN do:
char* stringPointer = *str;
(WARNING: untested code!)
Thanks in advance.
(oh and sorry if this is a really NOOBY question or the question is poorly constructed, I've just started out with c++ and stackoverflow)
EDIT: Ok, so I understand what the char* str means. It means that when you reference *str, it means that you're accessing the first character in memory. Ok, I get it now. But, what does const mean?
const char* str = "random text here";
On the right hand side, the "random text here" defines a string literal which actually is an array of type const char[17] (including the null terminator character). When you assign that array to const char* str it decays to a pointer that points to the first character. You cannot modify the string literal through the pointer because string literals are stored in read-only memory, so the following would be illegal: str[0] = 'x';
char[] str = "string here";
This one is different. It defines the char array str which has the same size as the string literal on the right hand side (const char[12]). The string literal will be copied into the array str, so you will be able to modify str. In this case, it would be legal to write str[0] = 'x';.
If you declare const char* sth ="mystring"
It will place mystring inthe memory and sth pointing to that its work like array but with direct access to memory
These are plain C-strings. A C string is always null terminated. In other words- it has '\0' at the end. So you need only the place in memory where the string starts and you can find when it ends.
For pointer arithmetic these [] brackets are only syntax sugar. str[] is the same as *str and str[1] is the same as *(str+1) only incrementing the pointer by one char (8 bits) and getting the address of the second element.
C doesn't really have strings. A string is an array of characters, terminated by a nul (0). Now arrays and pointers in C are closely linked, and a char * or const char * usually points to a string, but only in the same way as other pointers usually point to arrays. An individual char * might only point to a single character, you have to know from context, just as an int * might point to one integer or an array of integers.
Because strings are handy, there's a special syntactical rule for strings literal. A string literal in quotes becomes a const char * (in fact its type is char * for backwards compatibility). So in this sense, C has strings. But all that is happening is that the string is being laid out in the data section of the program, then its address taken.
Related
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'm new comer to C++, so I'm very confused about the code below:
const char* headers[]= {"apple","pear","tree"};
So is this line supposed to create "an array of pointers to char"? (Maybe i'm wrong). If so, why such array of pointers being assigned to an array of strings?
Also I'm confused why bother to have such pointer array? Can't we simply do sth like: int array [5] = { 1, 2, 3, 4, 5 };
All such pointer/reference stuff in C++ are so confusing and difficult for people like me from Java world.
Many thanks!
Hope this will help, here is a basic explanation of what the line means with some crude illustrations.
Please note that all addresses are made up, and some things are simplified in hopes of making the concept easier to see. Forgive the crude art, I am far from an artist!
const char* headers[]= {"apple","pear","tree"};
This line is telling the compiler that you would like to allocate an array. The elements in the array will be of type char*. The const keyword tells the compiler that the object or variable is not modifiable. char* is the type of elements in the array. headers is the variable name, and the brackets [] indicate that headers is an array. The rest of the line is an initializer for the array. header will have 3 elements of type char* which basically means “pointer to a string of characters”.
The compiler will also allocate memory and initialize the array by filling it with each of the 3 strings in the braces {"apple","pear","tree"}
The first element in the header array header[0] will contain a pointer to the memory where the string “apple” is located.
The second element in the header array header1 will contain a pointer to the memory where the string “pear” is located.
const char* headers[]= {"apple","pear","tree"};
"If so, why such array of pointers being assigned to an array of strings?"
Because in C there is no such thing as a string. There is instead a sequence of characters with a trailing 0 at the end.
C++ has std::string.
const char* headers[]= {"apple","pear","tree"};
means headers is an array of char pointers. Simple way to dissect it to look at non array version
const char * fruit = "pear";
This creates a literal "pear\0" (note the 0 added on the end) and then creates a variable that points to the 'p' character. Ie it contains the address of where that 'p' is stored. Now back to
const char* headers[]= {"apple","pear","tree"};
This creates 3 literals 'apple\0', 'pear\0', 'tree\0'
It create a 3 entry array of char * pointers
It sets header[0] to point to the 'a' of apple
It sets header[1] to point to the 'p' of pear
It sets header[2] to point to the 't' of tree
Answering the question as asked:
const char* headers[]= {"apple","pear","tree"};
This line defines a variable named headers, with type "array of 3 pointers to const char" (where 3 is deduced from the number of initializers). The pointers are set to point to 3 string literals, which they remain immutable during program execution.
I am learning C++. In the program shown here, as far as I know, str1 and str2 store the addresses of first characters of each of the relevant strings:
#include <iostream>
using namespace std;
int main()
{
char str1[]="hello";
char *str2="world";
cout<<str1<<endl;
cout<<str2<<endl;
}
However, str1is not giving any warnings, while with str2 I get this warning:
warning: deprecated conversion from string constant to 'char*' [-Wwrite-strings]
char *str2="world";
What's different between these two declarations that causes the warning in the second case but not the first?
When you write
char str1[] = "hello";
you are saying "please make me an array of chars that holds the string "hello", and please choose the size of the array str1 to be the size of the string initializing it." This means that str1 ends up storing its own unique copy of the string "hello". The ultimate type of str1 is char[6] - five for hello and one for the null terminator.
When you write
char *str2 = "world";
you are saying "please make me a pointer of type char * that points to the string literal "world"." The string literal "world" has type const char[6] - it's an array of six characters (five for hello and one for the null terminator), and importantly those characters are const and can't be modified. Since you're pointing at that array with a char * pointer, you're losing the const modifier, which means that you now (unsafely) have a non-const pointer to a const bit of data.
The reason that things are different here is that in the first case, you are getting a copy of the string "hello", so the fact that your array isn't const isn't a problem. In the second case, you are not getting a copy of "hello" and are instead getting a pointer to it, and since you're getting a pointer to it there's a concern that modifying it could be a real problem.
Stated differently, in the first case, you're getting an honest-to-goodness array of six characters that have a copy of hello in them, so there's no problem if you then decide to go and mutate those characters. In the second case, you're getting a pointer to an array of six characters that you're not supposed to modify, but you're using a pointer that permits you to mutate things.
So why is it that "world" is a const char[6]? As an optimization on many systems, the compiler will only put one copy of "world" into the program and have all copies of the literal "world" point to the exact same string in memory. This is great, as long as you don't change the contents of that string. The C++ language enforces this by saying that those characters are const, so mutating them leads to undefined behavior. On some systems, that undefined behavior leads to things like "whoa, my string literal has the wrong value in it!," and in others it might just segfault.
The problem is that you are trying to convert a string literal (with type const char*) to char*.
This question already has answers here:
How to initialize all members of an array to the same value?
(26 answers)
Closed 8 years ago.
I have been wondering, why can I not write my code like so:
char myChar[50];
myChar = "This is a really cool char!";
Or at least like this:
char myChar[50];
myChar[0] = "This is a really cool char!";
The second way makes more sense that it should work, to me, seeing that I would
start the array at the point I want it to start moving the letters into each spot in the
array.
Does anyone know why C++ does not do this? And can you show me the reasoning behind the
right way to do it?
Thank you all in advance!
The first line:
char myChar[50];
...allocates an array of 50 characters on the stack. The second line:
myChar = "This is a really cool char!";
Is attempting to assign a const static string (which exists in read-only memory in the text segment of your code) to the address of the beginning of the array. This is an incompatible LVALUE/RVALUE matcing/assignment. This approach:
const char* myChar = "This is a really cool char";
Will work, as the assignment of a pointer to address a string literal must be done at initialization time. There are potential exceptions, as in assigning a const char* pointer to a string literal like so:
/*******************************************************************************
* Preprocessor Directives
******************************************************************************/
#include <stdio.h>
/*******************************************************************************
* Function Prototypes
******************************************************************************/
const char* returnErrorString(int iError);
/*******************************************************************************
* Function Definitions
******************************************************************************/
int main(void) {
int i;
for (i=(-1); i<3; i++) {
printf("i=%d - Error String:%s\n", returnErrorString(i));
}
return 0;
}
const char* returnErrorString(int iError) {
const char* ret = NULL;
switch (iError) {
case 0:
ret = "No error";
break;
case (-1):
ret = "Invalid input";
break;
default:
ret = "Unknown error";
break;
}
return ret;
}
You might benefit from reading the post in my references below. It will give you some info on how code, variables, constants, etc, are broken into different segments of the final binary, and why some approaches don't even make sense. Also, it would be beneficial to read up a bit on terminology like integer literals, string literals, l-values, r-values, etc.
Good luck!
References
Difference between declared string and allocated string, Accessed 2014-05-01, <https://stackoverflow.com/questions/16021454/difference-between-declared-string-and-allocated-string>
You must initialise the array of chars inside the declaration of the array. There is actually no reason for not doing so, as if not, your array will contain garbage values until you initialise it. I advise you to look at this link:
Char array declaration and initialization in C
Also, you are allocating a char array of size 50 but only using 28 elements of it, this would appear to me to be a waste...
Try the following for simple string initialisations:
char mychar[11] = "hello world";
Or...
char *mychar = "hello world";
I hope this helps...
If you want to think of this in holistic terms, the reason is because myChar isn't a string -- it's just an array of char. Hence "FooGHBar" and char [50] are completely different types. Related in a sense, but really not.
Now some might say, "but "FooBar" is a string, and char [50] is really just a string too." But that is going on the assumption that myChar is the same as "FooBar", and it's not. It's also assuming that the compiler understands that both char[50] and char* are pointers to strings. The compiler doesn't understand that. There could be any manner of thing stored in those places that have nothing to do with strings.
"But myChar is just a pointer?"
That is the reason why people think that the assignment should be a natural thing -- but the fundamental premise is wrong. myChar is not a pointer. It is an array. A name which refers to an array will decay into a pointer at the drop of a hat, but an array is not a pointer.
I'm new in c++ language and I am trying to understand the pointers concept.
I have a basic question regarding the char pointer,
What I know is that the pointer is a variable that stores an address value,
so when I write sth like this:
char * ptr = "hello";
From my basic knowledge, I think that after = there should be an address to be assigned to the pointer, but here we assign "hello" which is set of chars.
So what does that mean ?
Is the pointer ptr points to an address that stores "hello"? or does it store the hello itself?
Im so confused, hope you guys can help me..
Thanks in advance.
ptr holds the address to where the literal "hello" is stored at. In this case, it points to a string literal. It's an immutable array of characters located in static (most commonly read-only) memory.
You can make ptr point to something else by re-assigning it, but before you do, modifying the contents is illegal. (its type is actually const char*, the conversion to char* is deprecated (and even illegal in C++11) for C compatibility.
Because of this guarantee, the compiler is free to optimize for space, so
char * ptr = "hello";
char * ptr1 = "hello";
might yield two equal pointers. (i.e. ptr == ptr1)
The pointer is pointing to the address where "hello" is stored. More precisely it is pointing the 'h' in the "hello".
"hello" is a string literal: a static array of characters. Like all arrays, it can be converted to a pointer to its first element, if it's used in a context that requires a pointer.
However, the array is constant, so assigning it to char* (rather than const char*) is a very bad idea. You'll get undefined behaviour (typically an access violation) if you try to use that pointer to modify the string.
The compiler will "find somewhere" that it can put the string "hello", and the ptr will have the address of that "somewhere".
When you create a new char* by assigning it a string literal, what happens is char* gets assigned the address of the literal. So the actual value of char* might be 0x87F2F1A6 (some hex-address value). The char* points to the start (in this case the first char) of the string. In C and C++, all strings are terminated with a /0, this is how the system knows it has reached the end of the String.
char* text = "Hello!" can be thought of as the following:
At program start, you create an array of chars, 7 in length:
{'H','e','l','l','o','!','\0'}. The last one is the null character and shows that there aren't any more characters after it. [It's more efficient than keeping a count associated with the string... A count would take up perhaps 4 bytes for a 32-bit integer, while the null character is just a single byte, or two bytes if you're using Unicode strings. Plus it's less confusing to have a single array ending in the null character than to have to manage an array of characters and a counting variable at the same time.]
The difference between creating an array and making a string constant is that an array is editable and a string constant (or 'string literal') is not. Trying to set a value in a string literal causes problems: they are read-only.
Then, whenever you call the statement char* text = "Hello!", you take the address of that initial array and stick it into the variable text. Note that if you have something like this...
char* text1 = "Hello!";
char* text2 = "Hello!";
char* text3 = "Hello!";
...then it's quite possible that you're creating three separate arrays of {'H','e','l','l','o','!','\0'}, so it would be more efficient to do this...
char* _text = "Hello!";
char* text1 = _text;
char* text2 = _text;
char* text3 = _text;
Most compilers are smart enough to only initialize one string constant automatically, but some will only do that if you manually turn on certain optimization features.
Another note: from my experience, using delete [] on a pointer to a string literal doesn't cause issues, but it's unnecessary since as far as I know it doesn't actually delete it.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the difference between char s[] and char *s in C?
Difference between char a[]=“string”; char *p=“string”;
Firstly, i would like to ask where can i learn all the basics of char* and char[].
Most of the time i find myself struggling with how to compare and how to declare.
Example 1 :
char *test = "hello world";
This will produce the following warning at compilation :
warning: deprecated conversion from string constant to ‘char*’
Example 2 :
vector<char*> test2;
test2.push_back("hello world");
This will produce an error of copying a string.
So the solution i come up with is :
(is this correct?)
vector<char*> test3;
char *str1 = "hello world"
test3.push_back(str1);
Thanks in advance! :)
============================================
Two good reads provided by people here :
What is the difference between char s[] and char *s?
Difference between char a[]="string"; char *p="string";
Your question "where can i learn all the basics of char* and char[]," is probably too general, but you can try reading the C++ spec.
Fix example 1 by changing it to
char const *test = "hello world";
Fix example 2 by changing it to
vector<std::string> test2;
test2.push_back("hello world");
Or if you really want a vector of non-owning pointers to c-strings:
vector<char const *> test2;
test2.push_back("hello world");
You can learn a lot about char*/char[] in your favorite book on C (not on C++, because C++ provides much better facilities for representing strings than C does).
The declaration/assignment
char *test = "hello world";
should be
const char *test = "hello world";
because string literals are pointers to constants. If you want a vector of strings in C++, you do it like this:
std::vector<std::string> test2;
test2.push_back("hello world");
This works, because string literals can be implicitly converted to std::string.
So the thing to remember is the difference between a pointer to a value and the value itself.
The value itself is the literal value that a variable represents as stored in memory.
A pointer is the address in memory that some value is stored at.
Pointers are useful because they allow you to access, change, and preserve changes in information across multiple functions / methods, which comes in handy when you realize you can only return one value from any function, but sometimes you want a lot more information than that.
The thing about arrays is that, while a lot of people don't realize this when first learning C++, they are pointers. A[0] isn't a variable, it's a pointer to a memory address. Arrays are handy because when declaring an array, you segment off a portion of memory reserved for use for that array. This is useful because it allows you to access the values stored in that block of memory very very quickly.
So really, there's not that much difference between declaring a pointer (char*) and an array (char[]) other than that the pointer will refer to a single location in memory while the array will refer to set of contiguous locations in memory.
To learn more about pointers and how to use them properly, visit http://www.cplusplus.com/doc/tutorial/pointers/ .