1

I need to clarify my concepts regarding the basics of pointer initialization in C++. As per my understanding, a pointer must be assigned an address before putting some value using the pointer.

int *p;
*p=10; //inappropriate
cout << *p <<"\n";

This would probably show the correct output (10) but this may cause issue in larger programs since p initially had garbage address which can be anything & may later be used somewhere else in the program as well.So , I believe this is incorrrect, the correct way is:

int *p;
int x=10;
p=&x;  //appropriate
cout << *p <<"\n";

My question is, if the above understanding is correct, then does the same apply on char* as well?:

const char *str="hello";  // inappropriate
cout << str << "\n";
//OR
const string str1= "hello";
const char str2[6] ="world";
const char *str=str1;  //appropriate
const char *st=str2;  //appropriate
cout << str << st << "\n";

Please advice

Ashish
  • 83
  • 1
  • 7
  • 1
    the char equivalent of `int *p; *p = 10;` would be `char *s; *s = 'h';`, not what you wrote – M.M Aug 05 '16 at 03:53
  • FYI You can manually assign an address to a pointer (see [here](http://stackoverflow.com/a/4532074/1559401)). In your case if you have an address `10` you can do `int* p = (int *)10`. You can go further with this as displayed [here](http://stackoverflow.com/a/32631614/1559401). This is especially useful when working on an embedded system and mostly when writing code for a microcontroller. – rbaleksandar Aug 05 '16 at 04:37

2 Answers2

5

Your understanding of strings is incorrect.

Lets take for example the very first line:

const char *str="hello";

This is actually correct. A string literal like "hello" is turned into a constant array by the compiler, and like all arrays it can decay to a pointer to its first element. So what you are doing is making str point to the first character of the array.

Then lets continue with

const string str1= "hello";
const char *str=str1;

This is actually wrong. A std::string object have no casting operator defined to cast to a const char *. The compiler will give you an error for this. You need to use the c_str function go get a pointer to the contained string.

Lastly:

const char str2[6] ="world";
const char *st=str2;  //appropriate

This is really no different than the first line when you declare and initialize str. This is, as you say, "appropriate".


About that first example with the "inappropriate" pointer:

int *p;
*p=10; //inappropriate
cout << *p <<"\n";

This is not only "inappropriate", this leads to undefined behavior and may actually crash your program. Also, the correct term is that the value of p is indeterminate.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
  • Thanks for your answer!! I understand that char *str="hello" causes str to point to 'h'. But my question is like you said for interger & other datatype pointers, we need to assign some address first before assigning the target value to it.Like int *p; *p=10 -- this is wrong, but char *str="hello" is correct.But in this case why it does not cause issue as here also we are assigning directly the target value without any address? – Ashish Aug 08 '16 at 17:15
  • @Ashu In C++ a string literal like `"hello"` is an array of constant `char`. The array is created by the compiler and stored somewhere (irrelevant where) and its lifetime is as long as the program is running. Like all arrays when using it, it decays to a pointer to its first element. Basically that's what happens when you do `const char* str = "hello;"` – Some programmer dude Aug 09 '16 at 05:32
1

When I declare a pointer

int *p;

I get an object p whose values are addresses. No ints are created anywhere. The thing you need to do is think of p as being an address rather than being an int.

At this point, this isn't particularly useful since you have no addresses you could assign to it other than nullptr. Well, technically that's not true: p itself has an address which you can get with &p and store it in an int**, or even do something horrible like p = reinterpret_cast<int*>(&p);, but let's ignore that.

To do something with ints, you need to create one. e.g. if you go on to declare

int x;

you now have an int object whose values are integers, and we could then assign its address to p with p = &x;, and then recover the object from p via *p.


Now, C style strings have weird semantics — the weirdest aspect being that C doesn't actually have strings at all: it's always working with arrays of char.

String literals, like "Hello!", are guaranteed to (act1 like they) exist as an array of const char located at some address, and by C's odd conversion rules, this array automatically converts to a pointer to its first element. Thus,

const char *str = "hello";

stores the address of the h character in that character array. The declaration

const char str2[6] ="world";

works differently; this (acts1 like it) creates a brand new array, and copies the contents of the string literal "world" into the new array.

As an aside, there is an obsolete and deprecated feature here for compatibility with legacy programs, but for some misguided reason people still use it in new programs these days so you should be aware of it and that it's 'wrong': you're allowed to break the type system and actually write

char *str = "hello";

This shouldn't work because "hello" is an array of const char, but the standard permits this specific usage. You're still not actually allowed to modify the contents of the array, however.


1: By the "as if" rule, the program only has to behave as if things happen as I describe, but if you peeked at the assembly code, the actual way things happen can be very different.