3

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.

haccks
  • 97,141
  • 23
  • 153
  • 244
user971961
  • 65
  • 3
  • Here is a similar post with lots of good explanation: http://stackoverflow.com/questions/12877120/char-and-char-pointer – B.K. Sep 07 '13 at 22:44
  • Possible duplicate of [Where does the compound/string literals get stored in the memory?](http://stackoverflow.com/q/17890301/2455888). – haccks Sep 08 '13 at 01:36

6 Answers6

12

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)

Luchian Grigore
  • 236,802
  • 53
  • 428
  • 594
  • +1 never thought about it but I guess you're right, whenever you want to change a char* you end up creating a new one anyway. Will C optimize all the time? Or will it only do it when it is low on memory? – John Sep 07 '13 at 22:48
  • @John if this optimization happens, it isn't done at runtime, so the memory footprint isn't a factor. Dunno about C, but in C++ if you optimize for space and both literals are visible to the translation unit, I'm pretty sure most compilers will optimize this case. – Luchian Grigore Sep 07 '13 at 22:50
  • @John It depends on the compiler and compiler settings whether or not duplicate string literals will be folded into a single one. For example, Microsoft's C/C++ Compiler offers the [/GF (Eliminate Duplicate Strings)](http://msdn.microsoft.com/en-us/library/s0s0asdt.aspx) compiler option to control this behavior. – IInspectable Sep 07 '13 at 23:45
6

The pointer is pointing to the address where "hello" is stored. More precisely it is pointing the 'h' in the "hello".

Harman
  • 1,531
  • 1
  • 18
  • 31
2

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

Mike Seymour
  • 235,407
  • 25
  • 414
  • 617
  • Also, you get compiler warnings (but of course you can disable them if you want to). – rsethc Sep 07 '13 at 23:14
  • Another note, you only run into problems if you try to set values in a constant array. However, assigning to a `char*` instead of a `const char*` doesn't actually cause any problems on its own (except that your compiler will yell at you and go "Hey, idiot! You should change that to a `const`!"). – rsethc Sep 07 '13 at 23:16
1

The compiler will "find somewhere" that it can put the string "hello", and the ptr will have the address of that "somewhere".

Mats Petersson
  • 119,687
  • 13
  • 121
  • 204
0

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.

John
  • 3,605
  • 5
  • 28
  • 46
  • The way you say this sounds like pointers are always some kind of hex value. They aren't hex values, they're just 32- or 64- bit unsigned integers. Hex is just a way you can write them, you just as well could say an address in binary, octal, decimal, or any other base. – rsethc Sep 07 '13 at 23:13
  • @rsethc Just aswell as you can have 16bit pointers for instance.. It's architecture specific. – Jite Sep 07 '13 at 23:16
  • Yes, any number of bits could be used as a pointer. 8,4,2,1... Although a 1-bit pointer would not be very useful. – rsethc Sep 07 '13 at 23:18
  • Hex is commonly used to display pointer addresses in several languages, is there a standard that I am not aware of? – John Sep 08 '13 at 00:37
  • Yes, it's commonly used to display addresses since it's easy to understand, but just because it's an address doesn't mean you must say it in hex. – rsethc Sep 08 '13 at 13:53
0

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.

rsethc
  • 1,715
  • 1
  • 14
  • 24
  • 1
    `"Hello"` in your cases are `string literals` and almost always `read-only` in `data segment`. You will most likely `segfault` if you try to modify them. The only way to "modify" is to make the pointer point to something else. – Jite Sep 07 '13 at 23:13
  • Yes but for demonstration purposes it's much like allocating an array. – rsethc Sep 07 '13 at 23:19
  • Actually I see where I am misleading, let me edit my answer a bit. – rsethc Sep 08 '13 at 13:54
  • I have never said it would or wouldn't be 'much like allocating an array', I was pointing out that you had a faulty section (about modifying a string literal). – Jite Sep 09 '13 at 10:13
  • Yes, I realize that I was wrong about modification, I think I got all of that out from the original answer. – rsethc Sep 09 '13 at 19:00