Sign in to follow this  
wendrowyek

Pointers/Arrays

Recommended Posts

wendrowyek    100
I'd like to make sure, that I fully understand what I've learned so far, regarding to pointers.

[code]#include <iostream>

using namespace std;


int main()
{
int nNumber, nNumber2; //declare integer variables.
nNumber = 50; //initialize variable with a value.
nNumber2 = 100; //Just here for an example.

int* pnNumbers[2] = {&nNumber, &nNumber2}; //create int pointer array that stores 2 addresses, number and number2.

//output to terminal
cout << "output for first element of the array: " << pnNumbers[0] << " and " << &pnNumbers[0] << " and " << *pnNumbers[0] << endl;
cout << "output for nNumber: " << &nNumber << " with the value of: " << nNumber << endl;
}
[/code]

Am I correct to say:

pnNumbers[0] will return the address of nNumber
&pnNumbers[0] will return the address of pnNumbers[0]
and *pnNumbers[0] will return the value stored in nNumber

It is a bit to wrap my mind around at first, I hope pointers make more sense to me, as I progress further
Also, I would like to know, difficulty wise, how hard is pointers to master, compared to other parts of C++?

Share this post


Link to post
Share on other sites
Hiwas    5807
[quote name='Wendrowyek' timestamp='1311562356' post='4839819']
I'd like to make sure, that I fully understand what I've learned so far, regarding to pointers.

[code]#include <iostream>

using namespace std;


int main()
{
int nNumber, nNumber2; //declare integer variables.
nNumber = 50; //initialize variable with a value.
nNumber2 = 100; //Just here for an example.

int* pnNumbers[2] = {&nNumber, &nNumber2}; //create int pointer array that stores 2 addresses, number and number2.

//output to terminal
cout << "output for first element of the array: " << pnNumbers[0] << " and " << &pnNumbers[0] << " and " << *pnNumbers[0] << endl;
cout << "output for nNumber: " << &nNumber << " with the value of: " << nNumber << endl;
}
[/code]

Am I correct to say:

pnNumbers[0] will return the address of nNumber
&pnNumbers[0] will return the address of pnNumbers[0]
and *pnNumbers[0] will return the value stored in nNumber

It is a bit to wrap my mind around at first, I hope pointers make more sense to me, as I progress further
Also, I would like to know, difficulty wise, how hard is pointers to master, compared to other parts of C++?
[/quote]

Your assumptions seem to be correct given the code. Pointers are a pain in the ass at first and it can take a while to get your head around them. I can't remember exactly how/where/why pointers started to click for me but I remember a the primary item which got me thinking along the correct lines was using arrays as pointers and the other way around. Basically using a combination of pointers to items versus pointer arithmetic. So, for instance:


struct Test
{
uint32_t a, b, c;
};

Test* t1 = new Test[ 2 ];
Test t2[ 2 ];

t1[ 0 ] = 0;
t2 [ 0 ] = 0;

Test* iter1 = t1 + 1;
*iter1 = 2;
t2[ 1 ] = 2;

The above is all equivalent work on t1 and t2, except where the "array" is stored in memory. I think making sure all of this clicks mentally was the primary starting point which got me thinking of arrays and pointers to things are basically the same things, just syntax differences. I think truly understanding that the above are basically the same is what finally got me working with pointers correctly.

Share this post


Link to post
Share on other sites
oler1s    585
> pnNumbers[0] will return the address of nNumber

Yes. Because pnNumbers is an array, pnNumbers[0] is the first element of the array. And the first element of the array is &nNumber, which is the address of nNumber.

> &pnNumbers[0] will return the address of pnNumbers[0]

Yes. Because & means address-of.

> and *pnNumbers[0] will return the value stored in nNumber

Yes. Because pnNumbers[0] gets you the address of nNumber. Then * dereferences the address. So you get nNumber, which evaluates to whatever value is stored in that variable.

> Also, I would like to know, difficulty wise, how hard is pointers to master, compared to other parts of C++?

Simple. Pointers themselves are trivial but some of the misinformation on pointers complicates learning. Pointers are just a form of indirection, and indirection is not a concept specific to C++.

Being able to deal with indirection is a pretty fundamental test of a programmer. If you need to take time to step through indirection, that's fine. But you should be able to obviously separate an object from some abstract reference to that object.

Share this post


Link to post
Share on other sites
frob    44903
[quote name='Wendrowyek' timestamp='1311562356' post='4839819']
Am I correct to say:

pnNumbers[0] will return the address of nNumber
&pnNumbers[0] will return the address of pnNumbers[0]
and *pnNumbers[0] will return the value stored in nNumber

It is a bit to wrap my mind around at first, I hope pointers make more sense to me, as I progress further
Also, I would like to know, difficulty wise, how hard is pointers to master, compared to other parts of C++?
[/quote]

Correct enough.

Back when I was teaching, I found most people had an easier time understanding pointers in the same way they understood post office boxes.


Every application gets its own unique set of boxes. The OS makes sure that the boxes in my program are kept separate from the boxes in your program. Box 5 in my program is completely different from box 5 in your program. Each program has several billion really tiny boxes. When you want to use them, the contents rarely fit in just a single box, they span multiple boxes. Since they span multiple boxes, we just refer to the first box in the set. Box 92 could be one tiny box long or span boxes 92-96, all you need to know is that it is labeled as address 92. Sometimes the system will also add gaps on purpose; there can be unused boxes in between stuff, and that's okay too.


int nNumber; That is one box. However, it is a big box. It could be composed of two little boxes, or four little boxes, or eight or more little boxes, just like in the real world you can have a tiny mailbox or a giant box that fits several large packages. On most modern C++ compilers and architectures, an int will span 4 memory addresses.

nNumber = 50; You just stuck a value into the box.

int* pnNumbers[2]; You made a multi-compartment box like you see at apartment buildings or office buildings. It has two sub-divisions. Each sub-box is big enough to store a box address.

int* pnNumbers[2] = {&nNumber, &nNumber2}; Just as the line above, you have a multi-compartment box. You filled the first compartment with the box number that nNumber lives at, and filled the second compartment with the box number that nNumber2 lives at.

pnNumbers[0] will return the address of nNumber, as you said. All you've done read the first compartment.

&pnNumbers[0] will return the address of pnNumbers[0], as you said. This will tell you the address of the first compartment.

*pnNumbers[0] will return the value stored in nNumber, as you said. Under the hood it will read the first compartment slot pNumbers, then the * at the front means it will jump over to that mailbox and read from it. There are several other ways to write a double dereference, such as **pnNumbers, or *(*(pNumbers+0)), and so on.




Share this post


Link to post
Share on other sites
rip-off    10976
[quote]
Also, I would like to know, difficulty wise, how hard is pointers to master, compared to other parts of C++?
[/quote]
Pointers are easy, but pointers are also hard.

The basics of pointers aren't too difficult. However, making even a small pointer-related error in C++ can result in some very confusing behaviour, which can take time to understand and debug. A simple pointer error can cause your program to crash, if you are lucky!

If you're unlucky though, a pointer error can corrupt other data in the process, which means you get weird results or inexplicable crashes in unrelated code. Tracking down the true source of such a bug can be a nightmare, especially when your program gets larger. These kind of bugs can lay silent for a long time, so you might make some trivial change one day and suddenly be presented with such a problem. You'll be scratching your head wondering how a small change introduced a crash, but maybe something was moved around in memory just enough to trigger the problem.
[quote]
I hope pointers make more sense to me, as I progress further...
[/quote]
One thing that beginner resources never emphasize is where pointers are actually used. This is a list of the broad areas where pointers get used:
[list]

[*] To represent the absence of a value. The NULL pointer, though aptly named the "Billion dollar mistake", does occasionally come in useful. A game-related example might be a heat seeking missile. It might have a pointer to its target. However, if it is launched and there are no heat sources in range, it might have a NULL target and might streak off into the distance.

[*] To avoid copies. Imagine a large class, or one that is otherwise expensive to copy, like a string with a million characters. You need to access it in another class or function. If you pass it by value, this will copy it, which could take a long time and might be totally unnecessary. Instead, you can pass a pointer to the existing data. The value of the pointer is copied and the data is accessed indirectly.

[*] To achieve pass by reference. This is used to modify parameters to a function, for example simulating "out" parameters.

[*] To interact with APIs that use pointers. A common example is C APIs, which use raw pointers extensively
[/list]
Note that all but the last option are discouraged in modern C++. Using C++ references, smart pointers such as std::shared_ptr/std::weak_ptr and containers like std::vector and helper classes like boost::optional are safer and more expressive.

When you're writing C++, you should avoid dealing with raw pointers where possible. Even when interacting with older APIs, you should try to wrap/hide them as much as possible, and try to wait until the last possible point before unwrapping a resource to a raw pointer to pass to the API.

Share this post


Link to post
Share on other sites
RoyCHill    92
[quote name='rip-off' timestamp='1311589751' post='4839931']
[quote]
Also, I would like to know, difficulty wise, how hard is pointers to master, compared to other parts of C++?
[/quote]
Pointers are easy, but pointers are also hard.

The basics of pointers aren't too difficult. However, making even a small pointer-related error in C++ can result in some very confusing behaviour, which can take time to understand and debug. A simple pointer error can cause your program to crash, if you are lucky!

If you're unlucky though, a pointer error can corrupt other data in the process, which means you get weird results or inexplicable crashes in unrelated code. Tracking down the true source of such a bug can be a nightmare, especially when your program gets larger. These kind of bugs can lay silent for a long time, so you might make some trivial change one day and suddenly be presented with such a problem. You'll be scratching your head wondering how a small change introduced a crash, but maybe something was moved around in memory just enough to trigger the problem.
[quote]
I hope pointers make more sense to me, as I progress further...
[/quote]
One thing that beginner resources never emphasize is where pointers are actually used. This is a list of the broad areas where pointers get used:
[list][*] To represent the absence of a value. The NULL pointer, though aptly named the "Billion dollar mistake", does occasionally come in useful. A game-related example might be a heat seeking missile. It might have a pointer to its target. However, if it is launched and there are no heat sources in range, it might have a NULL target and might streak off into the distance.[*] To avoid copies. Imagine a large class, or one that is otherwise expensive to copy, like a string with a million characters. You need to access it in another class or function. If you pass it by value, this will copy it, which could take a long time and might be totally unnecessary. Instead, you can pass a pointer to the existing data. The value of the pointer is copied and the data is accessed indirectly.[*] To achieve pass by reference. This is used to modify parameters to a function, for example simulating "out" parameters.[*] To interact with APIs that use pointers. A common example is C APIs, which use raw pointers extensively[/list]
Note that all but the last option are discouraged in modern C++. Using C++ references, smart pointers such as std::shared_ptr/std::weak_ptr and containers like std::vector and helper classes like boost::optional are safer and more expressive.

When you're writing C++, you should avoid dealing with raw pointers where possible. Even when interacting with older APIs, you should try to wrap/hide them as much as possible, and try to wait until the last possible point before unwrapping a resource to a raw pointer to pass to the API.
[/quote]

[class pointer] ->
[pointer] *
[address pointer]&

someone caught another pointer that was in your nose.

Share this post


Link to post
Share on other sites
rip-off    10976
[quote]
[class pointer] ->
[pointer] *
[address pointer]&

someone caught another pointer that was in your nose.
[/quote]
I have no idea what your post is trying to say, nor why it is quoting me.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this