23
char *str = "Hello";

char *ptr = str;
char *&rptr = str;

What is the difference between ptr and rptr? I understand rptr is a reference to a pointer(in theory) but how does it differ in terms of implementation with ptr?

Are references in C++ implemented using pointers?

apaderno
  • 28,547
  • 16
  • 75
  • 90
Sam
  • 719
  • 2
  • 6
  • 12
  • Possible duplicates: http://stackoverflow.com/questions/57483/difference-between-pointer-variable-and-reference-variable-in-c http://stackoverflow.com/questions/620604/difference-between-a-pointer-and-reference-parameter http://stackoverflow.com/questions/1948467/about-pointer-and-reference-syntax and probably more... – Alerty Jun 27 '10 at 20:07
  • 4
    Notice your code becomes invalid in about one year. It has been obsolete to point to string literals using `char*` for about ten years. – Johannes Schaub - litb Jun 27 '10 at 21:23
  • @Johannes - You mean the standard does not allow such string literals. Most of the books still use this notation. Where can I have a preview of such details? – Sam Jun 28 '10 at 05:19
  • 3
    @Sam: The C++ standard used to list the deprecated binding of string literals to `char*` in section D4. The C++0x FCD does not contain that entry anymore, which I guess means that the binding is no longer *deprecated* but now *illegal*, as Johannes correctly pointed out :) – fredoverflow Jun 28 '10 at 07:13
  • 4
    The important part is that if you want to point at a string literal, use a `const char*`. That has always been and will continue to be legal. – Tyler McHenry Jun 28 '10 at 15:06

3 Answers3

17

What is the difference between ptr and rptr?

If you do char *world = "World"; rptr = world; and then print str, it will print "World". If you do ptr = world; and then print str, it will print "Hello".

Johannes Schaub - litb
  • 496,577
  • 130
  • 894
  • 1,212
sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • 3
    i.e., rptr is an alias to string, ptr is a mere copy. If you point str somewhere else, it will affect rptr, but not ptr. In other words, you could say that str and rptr are 2 different variables (2 different names), but the same pointer. – jyoungdev Jun 27 '10 at 20:33
  • While indeed the gist of your answer is correct, notice that you cannot do `rptr = "World"` because `"World"` is not a `char*` pointer. The implicit conversion of the char array to a char pointer won't be done here, because it's a non-const reference. – Johannes Schaub - litb Jun 27 '10 at 21:25
  • @sepp2k it's still wrong. Let me fix the code to show you what is wrong. Now you have got same situation: You have an array but you try to bind a non-const reference to a `char*` to it - it won't work. It's just like `float a = 0; int &r = a;` fails. It's easy to overlook, but just as easy to understand once you see what's up here. – Johannes Schaub - litb Jun 28 '10 at 21:21
  • 1
    @JohannesSchaub-litb: My edited code compiles in g++ with -Wall -pedantic -ansi without warning. Note that I'm not doing `char*& something = anArray;`, I'm doing `char*& something = aPointer; something = anArray;`. – sepp2k Jun 28 '10 at 21:25
  • @sepp2k ohh i see now. I'm sorry for being that stupid. I even tried with codepad.org before to double-check, but i totally missed that this is really just an assignment. Lemme get another cup of coffee now. Cheers! – Johannes Schaub - litb Jun 28 '10 at 21:36
  • @sepp2k: What is the significance of this statement char*& something = aPointer; something = anArray; Are you doing this because you cannot directly point a string literal (ie "Hello") using char* directly as per the standard. – Sam Jun 29 '10 at 05:02
  • @TurkhanBadalov "Hello" is stored in read-only memory (or rather writing to it causes UB, so it *can* be stored in read-only memory). `str` is either a local or global variable (depending on where the OP's code is located) and not declared `const`. So it will most definitely not be stored in read-only memory (unless the compiler can prove that the variable is never written to, which is impossible in this case because we are writing to it). – sepp2k Mar 20 '17 at 14:29
  • @sepp2k but if we can change str then the memory leak appears. "Hello" is located somewhere, then we change the address where str points to. We loose the address of "Hello". You mean that locating "Hello" in Rom or not is dependent on compiler? And by specification nothing is wrong with changing str? And what do you mean by OP? – Turkhan Badalov Mar 20 '17 at 14:36
  • @TurkhanBadalov It's not like you can `free` string literals, so the memory is "leaked" either way. Yes, it's up to the compiler to decide whether or not to store string literals in a read-only section of memory. Not all platforms even support memory protection, so it'd be a bad idea for the standard to make assumptions about that. And yes, it's perfectly legal according to the standard to assign to `str` - it's just a variable like any other. – sepp2k Mar 20 '17 at 15:02
12

str stores the address (and therefore points) to a literal string, "Hello", which is stored somewhere in a read-only segment of memory.

ptr points to the same address as 'str'.

rptr basically points to 'str' (not to the same pointee as str, but to str itself). It might be unusual to use 'points to' for references but they're really very much like pointers themselves (in this case a pointer to a pointer) except with slight syntactical differences and the restriction that they cannot point to any other address during their lifetime.

It would be analogous to:

char** const rptr = &str;

Like a reference, rptr above cannot be assigned a new address (it cannot change what it's pointing to), but it can be free to change its pointee (which happens to be a pointer in this case to 'str').

*rptr = 0; // after this, str == 0

References are pretty much the same as a read-only pointer (not a mutable pointer to read-only pointee) only they don't require a dereferencing operator to get at the pointee (the referenced data):

char *str = "Hello";
char *&rptr = str;
rptr = 0; // after this, str == 0

The only difference from the above example with a read-only pointer to pointer is that we didn't have to use the operator*.

const references also have the unique property of being able to extend the lifetime of temporaries, but that's probably beyond the scope of the discussion.

stinky472
  • 6,737
  • 28
  • 27
5

Try this:

#include <iostream>
int main () {
    char *str1 = "Hello ";
    char *str2 = "World!";
    char *ptr = str1;
    char *&rptr = str1;
    rptr = str2;
    std::cout << ptr << str1 << std::endl;
}

It prints "Hello world!" because ptr is a char pointer pointing to the string literal "Hello ". rptr is a reference to a char pointer, so when you change it (the pointer, not the thing it points at.) you change str1. And thus ptr points to "Hello ". str1 points to "World!".

Kleist
  • 7,785
  • 1
  • 26
  • 30