5

I have a few questions. This isn't homework. I just want to understand better.

So if I have

int * b = &k;

  1. Then k must be an integer, and b is a pointer to k's position in memory, correct?

  2. What is the underlying "data type" of b? When I output it, it returns things like 0x22fe4c, which I assume is hexadecimal for memory position 2293324, correct?

  3. Where exactly is memory position '2293324'? The "heap"? How can I output the values at, for example, memory positions 0, 1, 2, etc?

  4. If I output *b, this is the same as outputting k directly, because * somehow means the value pointed to by b. But this seems different than the declaration of b, which was declared int * b = k, so if * means "value of" then doesn't mean this "declare b to the value of k? I know it doesn't but I still want to understand exactly what this means language wise.

  5. If I output &b, this is actually returning the address of the pointer itself, and has nothing to do with k, correct?

  6. I can also do int & a = k; which seems to be the same as doing int a = k;. Is it generally not necessary to use & in this way?

Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
Sean Hill
  • 1,297
  • 1
  • 13
  • 21
  • @intboolstring It's not a duplicate, since some of my questions are not addressed in that link. – Sean Hill Dec 25 '15 at 22:23
  • 1
    Well, you should have put the ones that weren't addressed there. – intboolstring Dec 25 '15 at 22:24
  • Also according to the comments in that link, some of the information is inaccurate. I don't want to potentially learn inaccurate things. – Sean Hill Dec 25 '15 at 22:24
  • 1
    @SeanHill: "some of my questions are not addressed in that link" Then you should have asked a single, specific question, not a random list of stuff. – Nicol Bolas Dec 25 '15 at 22:49

4 Answers4

3

1- Yes.

2- There's no "underlying data type". It's a pointer to int. That's its nature. It's as data type as "int" or "char" for c/c++.

3- You shouldn't even try output values of memory which wasn't allocated by you. That's a segmentation fault. You can try by doing b-- (Which makes "b" point to the "int" before it actual position. At least, to what your program thinks it's an int.)

4- * with pointers is an operator. With any data type, it's another data type. It's like the = symbol. It has one meaning when you put == and another when you put =. The symbol doesn't necesarilly correlates with it meaning.

5- &b is the direction of b. It is related to k while b points to k. For example, if you do (**(&b)) you are making the value pointed by the value pointed by the direction of b. Which is k. If you didn't changed it, of course.

6- int & a = k means set the direction of a to the direction of k. a will be, for all means, k. If you do a=1, k will be 1. They will be both references to the same thing.

Open to corrections, of course. That's how I understand it.

Desaroll
  • 323
  • 1
  • 9
  • Is (**(&b)) the same as *b? How do I interpret ** in this situation? – Sean Hill Dec 25 '15 at 22:29
  • Yes, they are the same. ** would mean two * operators. That's, they need a "pointer to a pointer" after them to work. And they return the value pointed by the value pointed by the value passed to them. Kinda a mess, but you can understand it like `*(*(&b))`. – Desaroll Dec 25 '15 at 22:32
  • Can it go infinitely deep? *******&b? – Sean Hill Dec 25 '15 at 22:39
  • Try it and see what your compiler does if if you that. – Peter Dec 25 '15 at 22:45
  • @SeanHill If you mean `int****** b;`, thats compiler dependent, but read http://c2.com/cgi/wiki?ThreeStarProgrammer. Also, what you just wrote causes errors, since **&b is the value of k, so adding another * will try to dereference `k` (an `int`). Even if it succeeds somehow, it will crash your program, since you try to access a memory location which might be protected. – David Szalai Dec 25 '15 at 22:47
  • @M.M - deleted prior comment. Will delete this one later. – rcgldr Dec 26 '15 at 01:24
2

In answer to your questions:

  1. Yes, b is a pointer to k: It contains the address of k in the heap, but not the value of k itself.

  2. The "data type" of b is an int: Essentially, this tells us that the address to which b points is the address of an int, but this has nothing to do with b itself: b is just an address to a variable.

  3. Don't try to manually allocate memory to a specific address: Memory is allocated based of the size of the object once initialized, so memory addresses are spaced to leave room for objects to be allocated next to each other in the memory, thus manually changing this is a bad idea.

  4. * In this case is a de-reference to b. As I've said, b is a memory address, but *b is what's at b's address. In this case, it's k, so manipulating *b is the same as manipulating k.

  5. Correct, &b is the address of the pointer, which is distinct from both k and b itself.

  6. Using int & a = k is creating a reference to k, which may be used as if it were k itself. This case is trivial, however, references are ideal for functions which need to alter the value of a variable which lies outside the scope of the function itself.

For instance:

void addThree(int& a) {
   a += 3;
}

int main() {
    int a = 3; //'a' has a value of 3
    addThree(a); //adds three to 'a'
    a += 2; //'a' now has a value of 8

    return 0;
}

In the above case, addThree takes a reference to a, meaning that the value of int a in main() is manipulated directly by the function.

This would also work with a pointer:

void addThree(int* a) { //Takes a pointer to an integer
   *a += 3; //Adds 3 to the int found at the pointer's address
}

int main() {
    int a = 3; //'a' has a value of 3
    addThree(&a); //Passes the address of 'a' to the addThree function
    a += 2; //'a' now has a value of 8

    return 0;
}

But not with a copy-constructed argument:

void addThree(int a) {
   a += 3; //A new variable 'a' now a has value of 6.
}

int main() {
    int a = 3; //'a' has a value of 3
    addThree(a); //'a' still has a value of 3: The function won't change it
    a += 2; //a now has a value of 5

    return 0;
}
Bryn McKerracher
  • 683
  • 6
  • 21
1

There are compliments of each other. * either declares a pointer or dereferences it. & either declares a (lvalue) reference or takes the address of an object or builtin type. So in many cases they work in tandem. To make a pointer of an object you need its address. To use a pointer as a value you dereference it.

Paul Evans
  • 27,315
  • 3
  • 37
  • 54
1

3 - If k is a local variable, it's on the stack. If k is a static variable, it's in the data section of the program. The same applies to any variable, including b. A pointer would point to some location in the heap if new, malloc(), calloc(), ... , is used. A pointer would point to the stack if alloca() (or _alloca()) is used (alloca() is similar to using a local variable length array).

Example involving an array:

int array_of_5_integers[5];
int *ptr_to_int;
int (*ptr_to_array_of_5_integers)[5];

    ptr_to_int = array_of_5_integers;
    ptr_to_array_of_5_integers = &array_of_5_integers;
rcgldr
  • 27,407
  • 3
  • 36
  • 61