# Learning C++ pointers help

16 replies to this topic

### #1KR3M3R

New Member

• Members
• 2 posts

Posted 06 January 2007 - 07:39 AM

Hi, I appreciate any help you guys can give me, I'm trying to learn C++ on my own, and was hoping you could tell me if I'm on the right track with respect to pointers.

First question:

int *pi2 = new int(1024);

this creates a pointer to an integer value of 1024 (as i understand it).
if I wanted to create a variable to use this value could I do this:

int num = *pi2; //?

or would I do this:

int num = **pi2;

or this:

int num = &pi2;

Second question:
int *pi3 = new int[1024];
As i understand it this creates an integer array of 1024 values pointed to by pi3. Is it possible to create a variable to access this array directly (and is that a desirable goal)?

As I've said I'm just learning this stuff and really appreciate your help and time in answering this question. Thanks again.
-Robb

### #2Reedbeta

DevMaster Staff

• 5311 posts
• LocationSanta Clara, CA

Posted 06 January 2007 - 08:46 AM

If pi2 is a pointer to an integer, than *pi2 is the integer value pointed to. This is called dereferencing the pointer. Conversely, if num is an integer, then &num is a pointer to num. So, num == *(&num), and pi2 == &(*pi2).

To declare an array without using new, you can write:
int nums[1024];
Note that arrays and pointers are syntactically identical in C++. This means you can use the name of an array as a pointer. Here, nums is an array, but it is also a pointer to the first element of the array. So, *nums == nums[0]. Conversely, any pointer can be accessed using array syntax, so *pi2 == pi2[0], and also pi2 == &pi2[0]. Moreover, array subscripting is equivalent to adding to a pointer. Therefore, num + 8 == &num[8], and *(num + 8) == num[8].

The difference between creating something using new and declaring it directly is all memory allocated with new has to be freed with delete, and things directly declared will be automatically de-allocated when they go out of scope. Generally, you will want to use static declarations unless you need to allocate dynamically. Some cases where you would need to use new:
(a) you want the allocated memory to hang around longer than normal, for instance if you're returning a pointer to it (since it would normally be destroyed when the function returns);
( you don't know until runtime how much memory you need. You can only declare static arrays with constant sizes, while you can use new to get arrays with variable sizes.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #3poita

Senior Member

• Members
• 322 posts

Posted 07 January 2007 - 03:50 AM

Pointers are just variables that hold memory addresses instead of the usual numerical values. The dereferencing operator (*) returns the value stored in the memory location that the pointer holds. The opposite of the dereferencing operator is the referencing operator (&), which returns the address of the operand.

int *pi2 = new int(1024);

As you know, this creates a pointer to an integer value of 1024. More specifically it creates a pointer to a memory address that has the integer value of 1024. The 'new' keyword allocates some memory for the integer and returns the memory address, which is now stored in pi2.

int num = *pi2;

So what does this do? The dereferencing operator (*) goes to the address pointed to by pi2 and gets the value stored there. As you know, pi2 points to a memory address that has 1024 stored there so this will make num == 1024.

int num = **pi2;

Now what you are doing here is dereferencing twice. We already know that *pi2 == 1024 so **pi2 == *(1024) == the value stored at memory address 1024. We have no idea what is stored at memory addess 1024 so it would most likely be some random integer, definitely not what you want to do.

int num = &pi2;

The referencing operator (&) returns the address of pi2. So you would most likely end up setting num to something like 2382346353 i.e. some random number that represents the memory address of pi2.

As Reedbeta already pointed out (pardon the pun), arrays and pointers are actually the same thing. What he means by that is that when you do something like this:

int nums[1024];

You are actually creating a pointer to the first element in the array. IMO it's not terribly obvious and can be quite confusing since there's nothing really there saying that you're creating a pointer but that is what you are doing and it's something you need to remember, especially when it comes to passing arrays as arguments to functions.

The most important thing to remember is that &(*p) == *(&p) == p. This is the pointer identity. Got a pointer to a pointer to a pointer? Just reference it 3 times and you're back at the value.

### #4.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 07 January 2007 - 01:55 PM

poita said:

int num = **pi2;

Now what you are doing here is dereferencing twice. We already know that *pi2 == 1024 so **pi2 == *(1024) == the value stored at memory address 1024. We have no idea what is stored at memory addess 1024 so it would most likely be some random integer, definitely not what you want to do.
Of course, you can't just dereference an int, you have to reinterpret_cast it to a pointer first

Quote

int num = &pi2;

The referencing operator (&) returns the address of pi2. So you would most likely end up setting num to something like 2382346353 i.e. some random number that represents the memory address of pi2.
As above but just the other way around. &pi2 yields a pointer (that points to a pointer, namely pi2), and num is an int. You can't assign a pointer to an int without doing a reinterpret_cast.

Quote

As Reedbeta already pointed out (pardon the pun), arrays and pointers are actually the same thing. What he means by that is that when you do something like this:

int nums[1024];

You are actually creating a pointer to the first element in the array.
Not quite, there is no pointer, and &nums won't do what you'd expect (it doesn't return an int**, but rather an int(*)[1024]). The variable 'nums' can be (implicitely) converted to a pointer, but it isn't the same as a pointer. There is no piece of memory that stores the pointer, which is why you can't reassign it with a different pointer or have it's address taken as a 'pointer to pointer'.

However, if you use this declaration as a parameter for a function, then it *is* a pointer. Confusing, eh? (if you want a function to only accept arrays of 1024 elements, use int(&nums)[1024] as a parameter)
-
Currently working on: the 3D engine for Tomb Raider.

### #5KR3M3R

New Member

• Members
• 2 posts

Posted 09 January 2007 - 12:46 AM

First, thanks for the help. I really appreciate it. Pointers are getting my head spinning and I'm still trying to get oriented.

I may have a follow up question in another day or so (while I process), but for now, I was wondering how often does a programmer actually use pointers and the like? When you're employed as a programmer, is this something one is likely to come across or just something CS teachers like to torture students with?
-Robb

### #6Reedbeta

DevMaster Staff

• 5311 posts
• LocationSanta Clara, CA

Posted 09 January 2007 - 12:49 AM

Oh, pointers are extremely common when programming in C++. There are other languages that don't have pointers, but they have references, which are pretty much the same thing. So, it's pretty vital to know pointers. Don't worry, understanding pointers will become easier with time and experience - it'll soon be second nature to you.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #7GroundKeeper

Valued Member

• Members
• 110 posts

Posted 10 January 2007 - 09:47 AM

Teaching a course in any referencing/pointer capable language will confirm Reedbeta. In most high-level languages I feel this is a bigger problem for the beginner since they hide the referencing all together.

What would we do without our pointers! I makes code so beautiful. ;)

### #8eddie

Senior Member

• Members
• 751 posts

Posted 10 January 2007 - 03:27 PM

Not only does it make it beautiful, but it makes it make sense.

In real life, you don't do "copy" semantics. If I'm talking about how many oranges you're holding, I don't go out and buy the same amount of oranges you have, just to count them. Instead I "point" to the ones you have, and count those.

It's as valuable a paradigm as "looking up" what others properties are in real life.

(God bless overworked analogies)

### #9SmokingRope

Valued Member

• Members
• 210 posts

Posted 18 January 2007 - 01:10 AM

As already shown pointers and arrays are similar.

char l_array[3]; EDIT: char *l_array = new char[3];
char *l_pointer = l_array;

And if you deal with c style strings you might end up looping through an array in just this way.
(Example 1)
for( l_pointer = l_array ; *l_pointer != 0 ; l_pointer++ )
{
cout << *l_pointer;
}


This code will print the contents of the array, stopping when the null character '0' is reached at the end.

You don't want to use the array itself in this situation.

(Example2)
for( ; *l_array != 0 ; l_array++ )
{
cout << *l_array;
}


In the code above, the contents of the array will still be printed. Note however, that the array itself will be pointing to the last element in the array and the rest of the contents of the array will be effectively lost.

In example 1 the pointer is assigned the address at which the array is also pointing to. At the end of each iteration of the loop, the pointer is then incremented by the size of one char, thus causing the pointer to 'point at' the next element in the array.

In example 2 there is no intermediary pointer. The array itself has been incremented by the size of one char and so now has a new first element. It would be possible then to address this array erroneously and write beyond the original array's boundary through a statement such as:

l_array[1] = 'i';

Were this array created using the syntax:

char l_array[3];

these problems would not be present.

In cases such as the one shown above, and when the array would have been passed as a parameter, such as:

void someFunc( char pData[] )

It is still possible to encounter this error.

### #10.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 18 January 2007 - 01:28 AM

SmokingRope said:

As already shown you can treat arrays and pointers the same.

Quote

You don't want to use the array itself in this type of situation.
You don't want to, but even if you did, you couldn't

Quote

for( ; *l_array != 0 ; l_array++ )
{
cout << *l_array;
}


In the code above, the contents of the array will still be printed.
No, you will get a compile error, stating that l_array is not a modifiable lvalue (or something similar).

Quote

Additionally, the error present in example 2 can be a significant source of memory leaks and/or memory corruption.
How can a program that refuses to compile leak memory?

One to never forget: arrays aren't pointers, even though they have similar syntax.
-
Currently working on: the 3D engine for Tomb Raider.

### #11.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 18 January 2007 - 01:42 AM

Btw, check this educational (yet funny) video about pointers: http://cslibrary.stanford.edu/104/
-
Currently working on: the 3D engine for Tomb Raider.

### #12SmokingRope

Valued Member

• Members
• 210 posts

Posted 18 January 2007 - 01:52 AM

I brought that on myself ...
i had meant in terms of an array definition such as:

char *l_array = new char[3];

### #13.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 18 January 2007 - 01:58 AM

Only in that piece of code l_array is not an array, but a pointer (that points to the first element of the newly allocated array)
-
Currently working on: the 3D engine for Tomb Raider.

### #14SmokingRope

Valued Member

• Members
• 210 posts

Posted 18 January 2007 - 02:32 AM

Although i have to agree with you, it's still possible to address a pointer in ways such as l_array[1] which makes the distinction irrelevant.

They both can be accessed as an array, and they both refer to a block of memory which stores a contiguous series of elements of the same type.

You're missing the point!

And i edited the post, for readability :surrender

### #15Reedbeta

DevMaster Staff

• 5311 posts
• LocationSanta Clara, CA

Posted 18 January 2007 - 09:16 AM

The distinction's not irrelevant; arrays and pointers are different things. It's not true that a pointer necessarily refers to a block of memory storing contiguous elements of the same type. Also with arrays there is no memory location storing the address of the first element, so for instance you can't take the address of the array, though you can take the address of a pointer. The fact that they both support subscripting, deferencing, and addition/subtraction doesn't mean they are interchangeable.
reedbeta.com - developer blog, OpenGL demos, and other projects

### #16.oisyn

DevMaster Staff

• Moderators
• 1842 posts

Posted 18 January 2007 - 10:43 AM

SpreeTree: actually I think you're the one missing the point . According to your reasoning, random access iterators are pointers as well as you can use the same syntax as with pointers (arithmetic, dereferecing, etc.). But they're clearly not pointers, they're just designed to behave like pointers (just like with arrays).

Reedbeta said:

so for instance you can't take the address of the array
Actually you can, and this yields a clear distinction with pointers:
int main()
{
int array[10];
int * ptr = array;

std::cout << typeid(array).name() << std::endl; // outputs "int[10]"
std::cout << typeid(ptr).name() << std::endl; // outputs "int*"

int ** ptrToPtr = &ptr;
int (*ptrToArrayOf10)[10] = &array;

ptrToPtr[2][3] = 34;  // indexes the 3rd element, or ptrToPtr+2, which is an int*, then indexes the 4th element from that pointer
ptrToArrayOf10[2][3]; // indexes the 3rd 10-element array (effectively array[20]), and then 3 elements next to that (array[23])

ptrToPtr = new int*[10]; // allocates array of 10 pointers
ptrToArrayOf10 = new int[20][10]; // allocates 200 ints consecutive in memory

void foo1(int(&)[10]);
void foo2(int*&);

foo1(ptr); // compile error
foo1(array); // ok

foo2(ptr); // ok
foo2(array); // compile error
}

Hey whatta ya know, they actually are different
-
Currently working on: the 3D engine for Tomb Raider.

### #17Reedbeta

DevMaster Staff

• 5311 posts
• LocationSanta Clara, CA

Posted 18 January 2007 - 04:16 PM

I stand corrected
reedbeta.com - developer blog, OpenGL demos, and other projects

#### 1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users