Pointers

Hello, I am looking for some examples involving pointers, Ive been trying to get my head around them, on and off for a few months, and I believe I understand the basics of what they do. But all the examples I can find of them, are basically the same, pointing to a variable, then the variable get changed using the pointer etc. But I am looking for examples that are more real life, not too complicated, but an example that will show what they are actually used for in pieces of code.

If anyone has any examples they would be willing to show, it would be greatly appreciated.

why not write yourself a nice linked list class or tree class with them? Those are classic pointer problems that have tons of source code / how to / etc online.

Before you go too far down a rabbit hole, pointers are NOT used as much as they used to be when the language was younger. They have their merits, but there are other ways to do most of the things that could only be done with pointers back when.


If you can make a little linked list program and get that working cleanly, you will know about as much about pointers as you need to for practical coding. For kicks you may also want to use a pointer to make an array (do this first, its simple) and do a bit of messing with the synax…

int *x = new int[10]; //this is an array of integers, really, just used a pointer to get there
int * ip = x;
for(j = 0; j < 10; j++)
{
*ip++ = j; //use a pointer to move through the array
}
for(j = 0; j < 10; j++)
{
x[j]= j; //same result as above loop, direct access array style
}

or basically understand the &x (get a pointer to), *x (dereference first location of a pointer, may be the ONLY location), and x[index] (access the nth location of a pointer, as if it were an array) and understand new/delete keywords. If you can read all this syntax and do the linked list... you are in pretty good shape..
I personally avoid * syntax and pointer math if at all possible, both are avoidable. * can make math code confusing (*x*=*y or z = *x * *y, goodness) and pointer math is almost always show-off code more than practical. The second one is the same as z = x[0] * y[0];
Last edited on
I will try the linked list idea, although I have never worked with them before, it is good practice. However, just for just now, I am doing the array/pointer like you suggested, but I am having some issues in understanding it i believe.

So the code I am trying is:

int main ()
{
int arr[3] {1,3,5};
int *ptr;

ptr = arr;
cout<< &arr << endl;
cout<< arr << endl;
cout<< ptr << endl;
cout<< &ptr << endl;
}

which returns

0x78799691dad0
0x78799691dad0
0x78799691dad0
0x78799691dac8

What I do not understand is why &ptr does not return the same address as the array. Is the pointer stored just before the array in memory? If so, why does ptr return the same address?
Also what is the point in the address operator on the line &arr, if printing arr, just gives the memory location too?

I think I need to read more to get a better understanding of pointers, but the documentation doesnt seem to be enough to get my head around it all
Last edited on
Because the pointer itself is stored in memory and as such, it has its own unique memory address just like any other variable.

An array is a constant pointer to its very first element, so when you send arr to the output stream, you will get the memory address of the very first element in your array displayed. Since your variable ptr points to that memory also, when you send ptr to the output stream, the same memory address is displayed. However, the pointer itself also has its own unique memory address on the stack. So when you send &ptr to the output stream, you're sending the memory address of the pointer itself to the output stream.

I think you're overthinking pointers as do most beginners. In truth, they're very simple to grasp. Forget about everything you know about pointers and just remember this: A pointer is a variable which stores a memory address of some other variable or structure. Done. If you're coming from a C# background, then think of pointers as reference variables. They refer to other variables. Why do we need them? Because they allow us to dynamically allocate memory and send objects from one function to another without copying them.

Uk Marine wrote:
An array is a constant pointer to its very first element

This is an oversimplification which is not helpful. An array is not a pointer.


kmce wrote:
cout<< &arr << endl;
cout<< arr << endl;
cout<< ptr << endl;

An array is implicitly converted to a pointer to its first element in many cases. When you print arr you are actually printing the address of the first element in arr (&arr[0]). ptr also points to the first element in arr so that is why it prints the same thing for both arr and ptr.

The first element in an array is stored at the first address of the array. This means that the address of the array (&arr) and the address of the first element in the array (&arr[0]) will be the same, and that is why &arr also prints the same as arr and ptr. There is however one difference. The type of &arr is a pointer to an int array of size 3 (int(*)[3]) which is different from the other two that has type pointer to int (int*).
Last edited on
This is an oversimplification which is not helpful. An array is not a pointer.

I think it's helpful to understand the relationship between pointers and arrays early on. An array name is indeed a constant pointer to the first element of the array. You can use the array name as a pointer for random access to elements.

EDIT: This could be helpful to the OP if interested: https://www.tutorialspoint.com/cplusplus/cpp_pointers_vs_arrays.htm
Last edited on
> An array name is indeed a constant pointer to the first element of the array.

No. Try running this small program:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
#include <iostream>
#include <type_traits>

template < typename T > void what_is( const T& x )
{
    std::cout << std::boolalpha
              << "is it an array? " << std::is_array<T>::value << '\n'
              << "is it a pointer? " << std::is_pointer<T>::value << '\n'
              << "how many bytes does its object representation take? " << sizeof(x) << '\n' ;

    if constexpr ( std::is_array<T>::value )
        std::cout << "how many elements are there in this array? " << std::extent<T>::value << '\n' ;
}

int main()
{
    int array[123] {} ;

    std::cout << "array\n" ;
    what_is(array) ; // array
                     // is it an array? true
                     // is it a pointer? false
                     // how many bytes does its object representation take? // 123 * sizeof(int)
                     // how many elements are there in this array?  100


    std::cout << "\n+array\n" ;
    what_is( +array ) ; // note: array to pointer decay
                        // is it an array? false
                        // is it a pointer? true
                        // how many bytes does its object representation take? // sizeof(pointer to object)
}

http://coliru.stacked-crooked.com/a/a63c6257b3bdbb9f

Array to pointer decay: https://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay
I had to learn that one recently too. Its not the same, C++ makes them look the same via a friendly syntax shortcut. However, because of the shortcut, you can treat them the same in almost all practical code, so while its technically incorrect, its practically / in code use still a very useful shortcut to know.

&ptr is the address of the address of the value you thought it would be.
its like saying
int ** p2d = &ptr;
ptr[0][0]; //this is arr[0]

Another thing I avoid is multi dimensional pointers :)

As for your program: congratulations, you have invented a reference. ptr is just a hand-rolled reference to arr. There are real world uses for this; say you are searching a container of objects looking for the maximum of some object.field. You can track the max with a pointer as a reference instead of a temporary object, saving copying a lot of information every time you find a bigger one as you iterate the container (say its not a container like an array where you could have just kept the index … though, if you think about the above for a bit, you will realize that an array index is a shortcut to a pointer as well -- arr[2] is the same as arr+2 is the same as ptr+2, though I am not sure arr can be used that way in syntax, I haven't had a need to try it). A pointer assignment only costs you an integer assignment, much cheaper than a fat class which under the hood may be doing 50+ times that amount of work.



Last edited on
What's this syntax?

+array in what_is( +array)

Im on my phone so I don't know if its a typo becuz I can't test it and it won't run on cpp.sh
Last edited on
> What's this syntax? +array in what_is( +array)

The + in +array is the built-in unary plus operator.
1) unary plus (promotion).
For the built-in operator, expression must have arithmetic, unscoped enumeration, or pointer type.
https://en.cppreference.com/w/cpp/language/operator_arithmetic#Unary_arithmetic_operators

A pointer type is expected, so array to pointer decay takes place:
There is an implicit conversion from lvalues and rvalues of array type to rvalues of pointer type: it constructs a pointer to the first element of an array. This conversion is used whenever arrays appear in context where arrays are not expected, but pointers are.
https://en.cppreference.com/w/cpp/language/array#Array-to-pointer_decay


> it won't run on cpp.sh

It is an old compiler, constexpr if statement requires C++17
https://en.cppreference.com/w/cpp/language/if#Constexpr_If

To make it run with the old compiler, we can change it to a plain old-fashioned if statement.
http://cpp.sh/6kjkk
Ahhh that's nice I never knew unary '+' had a function. I guess it's still not so useful though because it can only be used in this context and for casting to int.
Alright, I've never encountered situations where an array wasn't decayed into a pointer.

Thanks for the info.
Topic archived. No new replies allowed.