# 6.8 — Pointers and arrays

Pointers and arrays are intrinsically related in C++.

Similarities between pointers and fixed arrays

In lesson 6.1 -- Arrays (part i), you learned how to define a fixed array:

To us, the above is an array of 5 integers, but to the compiler, array is a variable of type int[5]. We know what the values of array[0], array[1], array[2], array[3], and array[4] are (9, 7, 5, 3, and 1 respectively). But what value does array itself have?

The variable array contains the address of the first element of the array, as if it were a pointer! You can see this in the following program:

On the author’s machine, this printed:

```The array has address: 0042FD5C
```

Note that the address held by the array variable is the address of the first element of the array.

It’s a common fallacy in C++ to believe an array and a pointer to the array are identical. They’re not. Although both point to the first element of the array, they have different type information. In the above case, array is of type “int[5]”, whereas a pointer to the array would be of type “int *”. We’ll see where this makes a difference shortly.

The confusion is primarily caused by the fact that in many cases, when evaluated, a fixed array will decay (be implicitly converted) into a pointer to the first element of the array. All elements of the array can still be accessed through the pointer, but information derived from the array’s type (such as how long the array is) can not be accessed from the pointer.

However, this also effectively allows us to treat fixed arrays and pointers identically in most cases.

For example, we can dereference the array to get the value of the first element:

Note that we’re not actually dereferencing the array itself. The array (of type int[5]) gets implicitly converted into a pointer (of type int *), and we dereference the pointer to get the value at the memory address the pointer is holding (the value of the first element of the array).

We can also assign a pointer to point at the array:

This works because the array decays into a pointer of type int *, and our pointer (also of type int *) has the same type.

Differences between pointers and fixed arrays

There are a few cases where the difference in typing between fixed arrays and pointers makes a difference. These help illustrate that a fixed array and a pointer are not the same.

The primary difference occurs when using the sizeof() operator. When used on a fixed array, sizeof returns the size of the entire array (array length * element size). When used on a pointer, sizeof returns the size of a memory address (in bytes). The following program illustrates this:

This program prints:

```20
4
```

A fixed array knows how long the array it is pointing to is. A pointer to the array does not.

The second difference occurs when using the address-of operator (&). Taking the address of a pointer yields the memory address of the pointer variable. Taking the address of the array returns a pointer to the entire array. This pointer also points to the first element of the array, but the type information is different (in the above example, int(*)[5]). It’s unlikely you’ll ever need to use this.

Revisiting passing fixed arrays to functions

Back in lesson 6.2 -- Arrays (part ii), we mentioned that because copying large arrays can be very expensive, C++ does not copy an array when an array is passed into a function. When passing an array as an argument to a function, a fixed array decays into a pointer, and the pointer is passed to the function:

This prints:

```32
4
```

Note that this happens even if the parameter is declared as a fixed array:

This prints:

```32
4
```

In the above example, C++ implicitly converts parameters using the array syntax ([]) to the pointer syntax (*). That means the following two function declarations are identical:

Some programmers prefer using the [] syntax because it makes it clear that the function is expecting an array, not just a pointer to a value. However, in most cases, because the pointer doesn’t know how large the array is, you’ll need to pass in the array size as a separate parameter anyway (strings being an exception because they’re null terminated).

We recommend using the pointer syntax, because it makes it clear that the parameter is being treated as a pointer, not a fixed array, and that certain operations, such as sizeof(), will operate as if the parameter is a pointer.

Favor the pointer syntax (*) over the array syntax ([]) for array function parameters.

An intro to pass by address

The fact that arrays decay into pointers when passed to a function explains the underlying reason why changing an array in a function changes the actual array argument passed in. Consider the following example:

```Element 0 has value: 1
Element 0 has value: 5
```

When changeArray() is called, array decays into a pointer, and the value of that pointer (the memory address of the first element of the array) is copied into the ptr parameter of function changeArray(). Although the value in ptr is a copy of the address of the array, ptr still points at the actual array (not a copy!). Consequently, when ptr is dereferenced, the actual array is dereferenced!

Astute readers will note this phenomena works with pointers to non-array values as well. We’ll cover this topic (called passing by address) in more detail in the next chapter.

Arrays in structs and classes don’t decay

Finally, it is worth noting that arrays that are part of structs or classes do not decay when the whole struct or class is passed to a function. This yields a useful way to prevent decay if desired, and will be valuable later when we write classes that utilize arrays.

In the next lesson, we’ll take a look at pointer arithmetic, and talk about how array indexing actually works.

### 105 comments to 6.8 — Pointers and arrays

• Hardik

Here also, the array being passed doesn’t decay, no?
Because then we wouldn’t have been able to change all of the elements of the array.

• Alex

The array does decay into a pointer when passed to the function. However, we can still use the pointer to modify the original array argument.

• Hardik

It means that the function parameter is also a pointer that is capable of holding the memory address of the array being passed !

• C++

Output :-
0x60ff08
0x60ff08
0x60ff08

Output :-
0x60ff0c
0x60ff0c
0x60ff08

Why The Outputs are different?
Is it because it(in the 2nd case) produces the memory address of the ptr var rather than the var it is pointing to? Plz Explain !

• Alex

In the last example, you’re printing the address of variable ptr, not the address that ptr is holding (which is array’s address). It should be consistent if you change to this:

• C++

"Is it because it(in the 2nd case) produces the memory address of the ptr var rather than the var it is pointing to?"

I said that btw ! But, Thanks đ !
No, I just wanted to experiment it !

• James Ray

The confusion is primary
The confusion is primarily

• Alex

Fixed, thanks!

• nikos-13

a) "When evaluated, a fixed array will âdecayâ into a pointer to the first element of the array. All elements of the array can still               be accessed through the pointer, but information derived from the arrayâs type can not be accessed from the pointer."

What do you mean with "All elements of the array can still be accessed through the pointer", how could this happen?

b) " Taking the address of the array returns a pointer to the entire array. This pointer also points to the first element of the array, but the type information is different (in the above example, int(*)[5])."

What do you mean with "int(*)[5]"?

• Alex

1) I mean a pointer pointing at the first element of an array can be used just like the array itself can. For example:

This works because of pointer arithmetic.

2) Don’t worry about it for now. It’s not something you need to know to progress.

• nikos-13

Thank you Alex!

• thang

Why ???? it still printed 4

//Finally, it is worth noting that arrays that are part of structs or classes do not decay when the whole struct or class is passed to a function. This yields a useful way to prevent decay if desired, and will be valuable later when we write classes that utilize arrays.

#include

struct new1
{
int a;
};

void printsize(new1 arr[]);

int main()
{
new1 arr[5];
printsize(arr);
}
void printsize(new1 arr[])
{
std::cout << sizeof(arr) << "n";
}

• Alex

You created an array of structs rather than a struct containing an array.

• thang

// it is worth noting that arrays that are part of structs or classes do not decay when the whole struct or class is passed to a function.//

I don’t understand why you said arrays do not decay when struct is passed to a function but in above code arr still has size is 4 provide that it decays in pointer…

sorry for my bad english .))

• Alex

Because you’re code isn’t doing what I’m suggesting. đ An array that is inside a struct will not decay:

An array of structs will still decay:

• thang

Oh thanks Alex, you are very enthusiastic

• Rohit

Is there any way of passing and array into a function without decaying it except using struct or classes or some other thing, just passing it through main()?

• Alex

Yes, there is. You can pass an array by reference:

But the syntax is messy. A better solution is just to use std::array. We cover std::array later in this chapter.

• Milos

Alex love your site so much it helped me a lot, i have one off topic quesiton,
I have searched today a little bit on the internet and found out that visual studio 2012+ don’t support windows form applications, i also found out there is a way to go around it but i dont have a tools menu or things like that (if u understand me), so my questions are how do i create real life applications for windows with c++ and where also can i use my c++ knowledge for creating some real life programs?

Thank you for everythig, you are the real HERO <3

• Alex

My understanding is that Windows Form applications are part of Microsoft .net, so you need to use managed C++ to create one. Unfortunately, I don’t have any knowledge on that topic, as I’ve never used .net (outside of some dabbling with C#).

• Chrisenyle

Hi, Alex
I have a question for you. Give this code:

….

I know this will print 20 (NumberOfElements * sizeof(int))
But I want to ask that how can it know the size of the array?
'Who' is holding the information of the array's length?

Thanks

• Alex

When you compile your program, the compiler builds a symbol table full of variable names and types as it encounters variables. The sizeof operator is resolved at compile time, and the size itself can be derived from the variable’s type. So when you compile this program, the compiler will replace “sizeof(array)” with 20 (which it knows because it knows that array is an array of 5 integers).

• Chrisenyle

Thank you very much!
You are amazing!

• raj

Thanks Alex.

• raj

why is my code failing?
int* test();
int main()
{
int* ptr=test();
for(int i=0;i<3;i++)
cout<<*(ptr+i)<<" ";

}
int* test()
{
int arr[3];
arr[0]=10;
arr[1]=20;
arr[2]=30;
return arr;

}

i am getting some garbage output instead of actual values in the array

• Alex

Variable arr is a local variable. That means it goes out of scope (and is destroyed) at the end of test.

However, you’re passing the address of arr back to main(). By the time main() gets the address, arr has already been destroyed. Consequently, main() is accessing a pointer that is now pointing to garbage.

• bert

I think there’s an extra word this time:

and we dereference the pointer to get the value at that the memory address the pointer is holding

I think you meant to drop the "that"

thanks!

• kris

First I’d like to thank you for this great site teaching everything about c++. But my problem is i want to learn everything how to write the program use a command prompt and eventually become good to able to code my own video games. I have more then 15 hours a day and this is great. Please provide a learning path or what to do or etc. So I’ll has a good perceptive of it all.

I believe you have my email thanks!!!! krisgoku2@hotmail.com

• Raquib

Hey Kris,

I am glad to see that you are passionate about learning how to code bottoms up, that’s necessary to start learning anything generally. I am not an expert but I might be able to share with you some suggestions that I received from many programmers over the years -

1- Get your hands dirty- Just start coding. This site can help you with that. Do the exercises/quizzes at the end of the chapters to begin with. Learn a concept and apply it. Man everyone starts with a hello world. Every single programmer I came in touch with said me the same thing. Follow the best practices in every code you write until it becomes your second nature. So, to quote from a fender squier affinity series slogan "stop dreaming, start playing" đ .

3- Aim small miss small (from Patriot) - Don’t expect to learn everything in one day. Start slow, have small goals don’t rush. Since you have a lot of time, make sure you complete each chapter properly. Don’t jump coz these lessons have been organized after a lot of time spent on how to do it.  These concepts are very important and will teach you the core C++. Once done you will be capable enough to absorb new concepts and more advanced topics. Which will require time, and lots of coding experience.

Best of luck. Happy coding đ

Regards,
Raquib

• Hi Alex,

I have a Query. I am Checking the below Program.

#include <iostream>

int main()
{
using namespace std;
int array[5] = {1,6,9,5,7};

std::cout << &array << "n" << &array[0];
std::cout << ‘\n’;
std::cout << *(&array) << "n" << *(&array[0]);
return 0;
}

When I run this program, I got the address for the first element of the array in both the cases(for the first cout). I understand the reason, As you rightly said: "The only difference is the type information that is returned. A pointer to the first element would have type int*, whereas a pointer to the whole array would have type (int[5] *).".

However, for the third cout, I am trying to dereference "&array" and "&array[0]".

So while dereferenceing, For "&array[0]", I got the correct result, i,e 1.
But for "&array", I got the memory address of the "array" again after dereferencing in stead of the array element.

I couldn’t understand the reason for this. Could you please explain, why *(&array) evaluated to memory address of the array rather then value of the array ?

• Alex

Remember that array decays to a pointer of some kind, and [] has an implicit deference. So:
*(&array[0]) evaluates array[0], giving you the value of element 0, which you then take the address of (giving you a pointer), which you then dereference to get the value of element 0 again.
*(&array) evaluates &array, which takes the address of the pointer to the array, essentially giving you a pointer to a pointer. You then dereference this to get back the original pointer to the array. This is why you’re getting an address here.

On the left hand side, *array dereferences the pointer to the array, giving you the value of element 0.

• Jason

What do you think of the following syntax for passing arrays to a function?

• Alex

It generally won’t work, unless arraySize is a macro. arraySize has to be a integer literal -- strangely enough, constexpr variables don’t seem to work here.

• abolfazl

• Darren

I remember there being some obscure syntax about arrays. Something like that myArray[n] is equivalent to *(myArray + n) which is equivalent to *(n + myArray) such that a statement like n[myArray], where n is an integer representing an array index, is actually valid syntax for access to the (n - 1)th array element. Not that you’d want to use such an odd thing.

• Alex

This is covered in the very next lesson. đ

• Nyap

so this statement

makes a pointer of type int and another 5 int variables (28 bytes in total on a modern system - 8 byte pointer & 5 4byte integers). The address of the first int variable is stored in the pointer, but since it’s not holding any information about the size of the array, there’s nothing stopping you from indexing out of the range of the array

Is that correct?

• Alex

No, int test[5] makes a fixed array with 5 elements, and takes 20 bytes. In most cases, when test is evaluated, it will decay into a temporary pointer.

There’s nothing stopping you from indexing an array out of range due to the way the subscript index works -- this is discussed in more detail in the lesson on pointer arithmetic.

• Jim

Sorry Alex my error.

• Jim

Alex,
After going over this lesson again.  There seems to be an error with the comments on both the programs that pass an array to a function.  The array is 32 bytes and the pointer is 4 bytes.

• Jim

Either that, or the print values backwards.

• Alex

Which example are you referring to?

• J3ANP3T3R

hey alex i just got back here for a review because i already reached chapeter 7.8 without fully understanding the chapter. it seems i misunderstood what "decay" means. it seems like the array when passed into the function decays into a pointer type which points to the first element of the array. by "decay" i first thought it would only include the first element in the array thus discarding the rest. taking a closer look at the examples above it is now clear to me that that wasn’t the case and in fact the passed array decays into a pointer type but can still be used just as a regular array only this time this is the actual array and not a copy.

just one question though, pointers holds only address and to get the value of that address we dereference a pointer with *. when an array is passed to a function and that array decays into a pointer type how come we can use the variable name of the array without * ? wouldn’t that be equivalent to getting the address of the element ?

example

void testarray(int array[])
{
std::cout << array[3] << std::endl;       // prints 44 not the address of 4th element
}

main()
{
int myarray[] = {11,22,33,44,55};

testarray(myarray);
}

• Alex

I’ll try to see if I can find a way to update the lesson to be clearer about what I mean by decay since it’s used in a non-obvious sense here.

Remember that operator[] does an implicit dereference, so array[3] is the same as *(array + 3).

• J3ANP3T3R

Thanks Alex your tutorials are very much appreciated.

• Jim

Alex.
When you modified the array element above, in the intro pass by address you used *ptr = 5;.  It seems like this statement actually does three operations at once?

1. Point to the address of the first element array[0].
2. Assign a new value to this element of 5.
3. Dereference the pointer.

Is that right?
How does this statement actually work?

• Alex

When changeArray() is called, the value of ptr is set by the caller -- in this case, it will point to the first element of array (array[0]). But that’s not specific to the line you indicate.
*ptr = 5 does two things:
1) It dereferences ptr, which gets the value at the address the pointer is pointing to (in this case, array[0]).
2) It assigned a new value of 5 to this element.

So it’s essentially saying array[0] = 5.

• Jim

Good Thanks for the clarification.

• Rob G.

Hi Alex. I want to leave this for you to repost in the proper section if u desire. I can’t find your section on dangling pointers.

My question is: under what circumstances should the programmer be vigilant about uncovering dangling pointers. I would think it daunting to look everywhere all the time, and I am wondering is there a more intelligent way of checking for them.

• Alex

I cover dangling pointers in the lesson 6.9.

One major problem with pointers is that there’s no way to tell whether they’re dangling. The burden is on the programmer to ensure that all pointers are valid.

That means if you deallocate memory or do something that will potentially leave pointers dangling, it’s on you to clean things up. One of the best ways to do that is to not have more than one pointer pointing to a given memory address (so that if you use one pointer to deallocate, you don’t leave the other dangling). Another good habit is to ensure you set your pointers to 0 or nullptr (unless they’re going to go out of scope anyway).

• Rob G.

Hi Alex,

In the process of review I recently learned that an array name is a pointer. In this lesson you were teaching how to assign a pointer(ptr) to an array(array). Does that mean the pointer (ptr) is pointing to another pointer, (array), that points to the address of the first element of the array?
e.g.

• Alex

An array name is not a pointer! An array name is an array that can decay into a pointer that points to the first element of the array (which you can then assign to another pointer if you desire).

So yes, in your example, ptr would point to the first element of array.

• Shiva

> When passing an array as an argument to a function, a fixed array decays into a pointer

Then how can the decayed pointer still use the [] syntax inside the function?

How does this work?

• Alex

Via pointer arithmetic, which I cover in lesson 6.8a, Pointer arithmetic and array indexing.

• Aymen

Hey Alex, been sat here for about 30 minutes trying to figure out whats going on and reading the comments to see if anyone has had similar questions.

I understand what you are saying about the question ^^ about dereferncing , the thing I dont understand how are we able to change an array via a pointer? I thought a pointer points to the address of a variable(s).

So we pass the array into the void function are we actually passing a pointer to the array as I changed the caller to

I got the message invalid conversion from int* to int. Is array automatically set to a pointer then?

Overall just confused, maybe because its half 10 and I got college tomorrow :P, Cheers for your help and time again Alex đ

• Alex

Remember that arrays decay to pointers in most situations. So when we pass the array as an argument to function changeArray(), it decays into a pointer that points into the first element of the array.

So function parameter ptr is pointing to the first element of the array.

When we dereference *ptr, we get the value at the first element of the array, which we can then assign to a different value (such as 5).

Note that this works with non-arrays too:

Does that make sense? I talk more about passing by address in lesson 7.3. If you’re still having trouble, you may want to jump ahead and read that lesson.

• Aymen

Thanks so much! I’m actually beginning to understand pointers finally and yeah I get it now. đ

• Nortski

There’s something I’m not quite getting my head around (although it is late here).
You say that when passing an array to a function:

is the same as:

So why can’t I change an element in the array with:

• Alex

Because both * and [] do a dereference, so you’re trying to dereference variable array twice.

Hi Alex. Thanks for the tutorials.
In the second difference between the pointers and arrays, when I check the type of the pointer to an array, i.e. using typeid(&array).name(), in Visual Studio I get ‘int (*) [5]’ and not ‘int[5] *’ . Is it because of differences in my and your compilers or it is typo?

• Alex

I see the same thing in Visual Studio 2015. typeid().name reports int (*)[5], but the visual debugger reports int[5] *. I like the “int (*)[5]” syntax better, since that matches how you’d actually declare a pointer to a fixed array. I’ll update the lesson.

• Robert Nawfal

I think in the chapter "Revisiting passing fixed arrays to functions " there is a little mistake. the //array decasy into a pointer here - comment should be one row below to the printSize(array);

• Alex

Quite right. Fixed!

• #include <iostream>

int main()
{
using namespace std;
//string myString = "Christopher";   //http://www.pornhub.com/view_video.php?viewkey=1040526098
char myStringArray[] = "Christopher";
int arraySize = sizeof(myStringArray)/sizeof(myStringArray[4]);
int nVowels = 0;

for (char *pnPtr = myStringArray; pnPtr < myStringArray + arraySize; pnPtr += 1)
{
switch (toupper(*pnPtr))
{
case ‘A’:
case ‘E’:
case ‘I’:
case ‘O’:
case ‘U’:
nVowels++;
break;
}
cout << "pnPtr: " << pnPtr << "\t*pnPtr: " << *pnPtr << endl;
}
cout << myStringArray << " has " << nVowels << " vowels." << endl;
}

//hello
Alex,i am having in a problem in this question..please explain ,,?

• Alex

You’re asking me to explain how this works? It’s using a for loop with a pointer to step through each character in the string, and if it’s a vowel, it increments nVowels.

• Quang

Hi Alex, thank you for this tutorial. but I wonder there are any other books, documentaries that can help me practice coding, i mean a book full of exercises like your quiz. Most regard!!!

• Thanks Alex..you’r a star

Suggestion:
You should exactly tell what cout prints when asked to print the address of a variable. Take this for example:

The part Arrays and Pointers in C++ is really confusing for beginners like me. I gave my 5 days to this chapter to clear everything and today at least not afraid of the title “Arrays and Pointers”. You can’t do anything better. Your site has the simplest explanation of Arrays and Pointers.

• Alex

Thanks for the feedback. I’ve rewritten parts of the article to try and make some of the points more clear. Talking about the sequential memory addresses of arrays is a good idea, but probably better for the next lesson. I’ll look at adding it there.

• 1. "To us, the above is an array of 5 integers, but to the compiler, array is a variable of type int[5]"
array is a pointer variable of type int[5], right? Add "pointer" before the term "variable" or let me know if I am taking it wrong.

2. Alex, help me get out of this big confusion:

In this program, if array is a variable of type int[5] and name is of char[], that points to the first element of that  array, what is decayed then. Code is printing what’s expected. array variable pointing to first element of array[5], and dereferencing it will definitely output the first element. Hope you understand what I am asking.

3. "Taking the address of the array returns a pointer to the entire array (in the above example, int[5] *), not just the first element (int *)." I can’t understand, what are you trying to say here. Do you mean this: "&array returns the address of entire array"? If yes, then again this program tricks me:

If &array is returning the address of the entire array, then why address of first element (&array[0]) is also same(printing the same address as &array)?

4. How to print the address of entire array and not just the address of its first element?
Sorry for bunch of questions, but this lesson is really confusing to me.

• Alex

Good questions.
1) Array has type int[5], not int*. This is why we can use sizeof() on it and get the size of the array, not the size of a pointer.
2) Arrays decay from their array types into a pointer type in most cases, including when they’re sent to cout. In practical terms, this rarely matters unless you need the size information.
3) The address of the first element and address of the entire array are the same. The only difference is the type information that is returned. A pointer to the first element would have type int*, whereas a pointer to the whole array would have type (int[5] *). The only case where this is likely to matter is when you’re doing pointer arithmetic. Incrementing a pointer to the first element will advance to the second element. Incrementing a pointer to the entire array will move to the memory address just beyond the array.
4) Again, they both point to the same address. It’s only the typing that’s different.

Let me know if this is clear, or how I could make the above lesson clearer to begin with.

• Tobias

Hi,

to question 3:

How is the correct syntax to initialize a pointer to an int arry? I want to do something like this:

Additionally, why does the following not work:

Greetings from germany,
Tobias

• Alex

ptr will point at the first element of array (index 0).

• One more conclusion, may be wrong:
I was testing arrays with different operators. Some operators cause it to break into a pointer and some doesn’t. If I am right(not sure, I am just a beginner), I found the solution of the question why array breaks into a pointer  when passed to a function. May be, the function call operator {()} is one of the operator that causes the array to break into a pointer, with no side effect. Please read my previous comment. I asked a question there.

• Alex

There are other operators that cause arrays to decay into pointers, such as unary operator+. So it’s not just the function call operator that causes decay.

• Thanks Alex, seems like you didn’t noticed this in my comment:

"This effectively allows us to treats(should be treat) an array as a pointer in most cases"

Typo is in the first paragraph after the first program posted in this lesson. The last line.

I am again with a question, If we can increment or decrement a pointer by 1 adrress by using increment decrement operators, why compiler complains when these operators are used directly on arrays to increment/decrement the address (something like (&array[0]) + 1) by 1 address? I know question will not explain what I am asking. Here is the program:

If array breaks into a pointer when evaluated, what is happening in 15th line? Is it also a special case? If yes, can I say that array remains array (and doesn’t decay into a pointer) when seen with an unary operator by the compiler?
I am not sure because dereference operator is also an unary operator.
Whatever it is, I am unable to understand why line no. 15 gives a compiler error. Can’t it print the address of the integer, that comes after the address of the last element in the array.

• Alex

++array is the equivalent of array = array + 1. A fixed array’s value (the address it points to) is considered const (it’s non-reassignable). You’re trying to change it, which is illegal.

• I found one more:
"In the fixed array case, the program allocates memory for a fixed array of length 5, and initializes that memory with the string âAlex\nâ"

"What usually happens is that the compiler places the string âAlex\nâ into read-only memory somewhere, and then sets the pointer to point to it"

If a string terminates with a null terminator and not with a newline escape sequence(\n), the "Alex\n" part should be "Alex" in both sentences. Take a look at my previous comment in this section. There are more typos.

A question…actually 2:
1. If an array decays into a pointer when evaluated, why sizeof(array) prints length*element value size. Does this means, the bracketed term (array) is not evaluated in this statement.
2. When I tried to get the address of a char variable by following program, it prints a strange character and not the address:

Why…???

• Alex

1) This is just a special case.
2) This is an interesting case you’ve found. You intended to print the memory address of variable value, but &value is being interpreted as a value of type char*. When you pass a value of type char* to std::cout, it prints that value as a string. Your variable value isn’t null terminated, so it prints a, and then runs off into uninitialized memory and prints some garbage before randomly hitting a 0, which acts as a null terminator.

• Typos:
"This effectively allows us to treats(treat) an array as a pointer in most cases"

char array variable is named "name". "szname" is undefined, so dereferencing it will cause a compile error. Remove "sz" from the pointer name in the last line.

"Note that ptr+1 does not return the memory address after pnPtr(should be ptr)"

• Alex

Fixed, thanks.

• sagar24

Hi,

I had a basic doubt regarding pointers. As per the pointer arithmetic, pnPtr+1 would refer to next object of the type that pnPtr points to. Thus, if pnPtr is an integer pointer than (pnPtr+1) would be (current_address_of_pnPtr + 4).
Consider the memory block as follows :
Memory location 0: pnPtr (Some_Int_Pointer. Assuming int takes 4 bytes)
Memory location 4: pchPtr (Some_Char_Pointer. Assuming char takes 1 byte)
Memory location 5: pnPtr1 (Some_Int_Pointer)

Now when we try to access (pnPtr+2), it would try to access memory location 8 (the last byte for pnPtr1).

Isnt that an undesirable situation. Wouldnt it return some gibberish value ?

Thanks!

• Alex

Yes, that is exactly what it would do. đ

That’s one of the many reasons you need to be careful using pointers.

• WGL

I have a question regarding a simple program which indexes using pointer arithmetic in order to reverse the case of a string. The code is this:

Unfortunately, the output gives a completely uppercase string, “THIS IS A STRING”, rather than the inverted case where a few letters should now be lowercase. I cannot see what the problem is! The code is not complicated, but admittedly I am not used to using pointers to index an array (I am a scientist writing a program which needs to be as efficient as possible - I have been led to believe that pointer arithmetic can produce faster code).

Any help would be appreciated!

• Gene

You probably discovered the reason for uppercase only a long time ago, but here’s an explanation in case you left this unsolved. The teacher in me will explode unless the answer can be revealed đ

You need to add “else” in between the first and second “if” clause (or you could use switch…case conditional structure instead).

The current logic of your original code says, “if current character is uppercase, make it lowercase”, then “if current character is lowercase” (and it always will be at this point), “make it uppercase”.

I’ve been a programmer for 23 years and I STILL sometimes miss obvious mistakes like this, so don’t feel bad about missing something so obvious.

There is a valuable underlying principle here that might help you spot things like this in the future:

When logical conditions are not behaving as expected, start by checking on the simplest things first, not the complicated things.

Another way to solve the problem is to swallow your pride and ask someone else to look your code over and tell you what’s wrong with it. Just be warned that it will be embarassing! I’ve spent hours at times trying to figure out why my code isn’t working, only to watch as someone who just glances at it sees the problem instantly!

It’s painful to do that, but you’ll help the other person feel smart and important. And that’s actually more valuable in the long run than figuring the code out yourself most of the time.

And I agree with everybody else about this site. One of the best C++ tutorials on the web. Thanks, Alex!

Hope this helps…

• Chris

First, thanks so much for your work on this…your tutorial is a huge help, Alex!

Walking through this portion on the use of pointers with arrays, I’m slightly confused by why using the reference operator (&) on a pointer created for a char array won’t return the value’s address, while one created for an int array will.

For example the following code:

Will output the following:
``` pnPtr: Christopher *pnPtr: C pnPtr: hristopher *pnPtr: h pnPtr: ristopher *pnPtr: r pnPtr: istopher *pnPtr: i pnPtr: stopher *pnPtr: s pnPtr: topher *pnPtr: t pnPtr: opher *pnPtr: o pnPtr: pher *pnPtr: p pnPtr: her *pnPtr: h pnPtr: er *pnPtr: e pnPtr: r *pnPtr: r pnPtr: *pnPtr: Christopher has 3 vowels. ```

…rather than a hex address for pnPtr.

While setting up a random integer array and carrying out the same process (sans vowel counting)…

…generates this output, with address output for the value of pnPtr and specific array entries for *pnPtr. (I expected the char array output to similar to this.)

``` pnPtr: 0xbfc6e1d8 *pnPtr: 1 pnPtr: 0xbfc6e1dc *pnPtr: 2 pnPtr: 0xbfc6e1e0 *pnPtr: 3 pnPtr: 0xbfc6e1e4 *pnPtr: 4 pnPtr: 0xbfc6e1e8 *pnPtr: 5 pnPtr: 0xbfc6e1ec *pnPtr: 10 pnPtr: 0xbfc6e1f0 *pnPtr: 20 ```

Can you explain why C++ deals with them differently or what I’m doing improperly?

• Alex

std::cout assumes that it should treat char* as a string, so it prints objects of that type as a string. For other types of pointers, it just prints the content of the pointer (the address the pointer is holding as a value).

• Andreas

I really appreciate your guide! THANKS

• Wow. I finally understand pointers! Yay!

That is a pretty hand way of stepping through an array.

• Realth

Why does cout << *(&szName) output the entire string ? Shouldn’t it only return the first character of szName ? &szName returns the address of the first element right ? So derefrencing it should give the first character.

Also why does my compiler complain when I try this :

I want pnPntr to point to the first Address of szName.

Yet this works,

Depending on what is on the left of szName, szName means completely different things!

I get mollie..

put a pointer declaration and suddenly szname is and address!

Is this just how it is ?

Excellent tutorials by the way!

• eric

*(&szName) is doing inverse operations, so it ends up just szName. The value of szName is actually an address (because it’s a pointer to the first address in the array), but the compilers treat it differently because it’s a string. The compiler jumps to the address in szName and reads the values starting from that address until it hits a null.
This is probably done for convenience, because when you’re looking at an array you usually want to see its contents and not its address. To access the first element, use *szName or szName[0]

After playing with it for awhile, I found that this will work setting to the address of the szName. I have no idea why, however. Intuitively, this should set pnPntr to the address of the first element in the array which szName points to, but the value of (int*)szName matches &szName:

However, changing the contents via “*pnPntr = “doesn’t work too well, as you’re limited to the first 4 characters’ ASCII values (my compiler had the added annoyance of outputting these in decimal rather than hex).

Hopefully someone else can be a little more clear on all this, because I don’t know enough about it to say, yet.

• Alex

The short answer to all your questions is that szName decays to a pointer to the first element of the array.

So when you say this:

You’re setting pnPntr to the content of szName, which is the address of the first array element. That’s likely what you’d intended.

When you say this:

You’re setting pnPntr to the address of szName, which itself is pointing to the first element of the array.

Assuming the former:

This is the same as pnPntr[0], so it should be no surprise it only prints the first element.

cout is smart enough to see that pnPntr is a char pointer, so it assumes you want to print the whole string.

Thanks for the great tutorial Alex.

In the above code:
const int nArraySize = 7;
char szName[nArraySize] = “Mollie”;

I’m confused why should nArraySize = 7, when Mollie is just six characters.
I tried replacing it with 6 but it won’t compile.

Thanks again.

• Quinn

You had forgotten to include the null terminating character, . Every C-string must end with the null terminating character, and as a direct result, all C-strings are sized to one larger than the string you’re putting into it. In essence, it would work out like this…

Alex covered this in much more detail in C-Style Strings, so I’d suggest revisiting that section to see it in action.

When you change nArraySize to equal 6, that meant that the szName array could only contain a string of five characters (because it MUST end with a null-terminating character, if it doesn’t, it causes overflows). So the compiler realizing this, issued a build error since this would inevitably, without fail, lead to an overflow. This is just one of the many little quirks of the C/C++ language, and computer programming in general, you’ll have to get used to. đ

• Yogesh Shastri

Dear Alex,

Thank you for providing this wonderful resource for learning C++. I was trying my luck at pointers, but when I wrote a code like this:

#include
#include
void main()
{
clrscr();
int arr[5]={1,2,3,4,5};
char name[]=”Pratyush”;
cout<< *arr++ <<endl;
cout<< *name++ <<endl;
getch();
}

I get error on line on which I use *arr++ and *name++ saying that an Lvalue is required. Could you please explain.

Regards and bets wishes.

• Sandesh

Yogesh,

L-Value means a quantity on left side of any equation or assignment.L-Values are always variables while values on right side(R-Values) are numbers or characters.The ++ operator requires varibles that is L-Values.

The dereferencing operator “*” has higher precedency than the increment by 1 “++” operator.If the program would have exceuted,while excecuting the first cout, the operation *arr would be excecuted first then ++.*arr would result the address of first element of array ‘arr’ as array name is a pointer that addresses the first element.the address would be a hexadecimal number and therefore not a variable and ++ statement would not execute.Therefore,it shows L-value(variable) required.

it is the same with second cout.* operator would now be the value of first element and therefore ++ would not execute.

i hope you understood it.

Cheers;Sandesh

• rawr

You say that *arr results in a hexadecimal number, yet when I type *arr it uses the value. Also, the code works with (*arr)++.

Is this because addresses are simply treated differently to pointers by the compiler?

• AUASP

“the dereferencing operator â*â has higher precedency than the increment by 1 â++â operator”
Actually the reverse is true.check any c++ associativity and precedence list.

• Yogesh Shastri

Great Site. A lot of things are said about sharing learning and wisdom, but a few are able to do it. You are one of them, and since you have done it with excellence, so kudos to you! I have tried to write tutorials for another programming language that I have learnt, but couldn’t do it, because of so many factors - so I can really appreciate your efforts. Thanks to you!

• Stuart

This is going over my head:

• miroslav

I’m sorry but would it be possible to explain? For example the ‘pnPtr <= szName + nArraySize)’

• Hmmm, not sure how I missed the original comment here. Sure, here’s the explanation.

In this example, szName is an array. As you have learned, arrays and pointers are intricately linked in C++. Let’s break this for loop into it’s 3 components and examine each one:

This is creating a new pointer named pnPtr and setting it to point to the first character in the name array. After this, pnPtr and szName will be holding the same address.

The tricky part of this is determining what szName + nArraySize means. Arrays are laid out contiguously in memory. If szName is the start of the array, and nArraySize is the length of the array, then szName + nArraySize must be the end of the array. So what this is really saying is, “while pnPtr hasn’t reached the end of the array, keep looping”.

Increment the pnPtr pointer to the next character.

So, putting it all together: “pnPtr is set to the start of the array. While it hasn’t reach the end of the array, do the loop, and then increment pnPtr to the next character”.

That’s it.

• Cory

For the last part, “Increment the pnPtr pointer to the next character.”, did you mean increment the point to the address of the next character?

• Alex

Yep.

• Alex,

Your site is wonderful, thanks for providing it. I was editing some of the examples you provide to see what happens with the output and I noticed something I cannot explain. When I substitute the following into your last example (Mollie/Vowels) I get the output 3, which makes sense.

But When I change the code to the below, the result becomes 4, which I do not understand. It is as if the program is counting the last whitespace character as a vowel. Can you explain this to me?

BTW, I am using Cygwin with Dev-C++ and the GNU compilers.

Thanks and best regards,
Pete

• When I ran your Lazy Brown Fox example with Visual C++ 2005, I got 3 vowels, not 4. So at the moment I’m not sure why you’re getting a different result.

My advise to you would be to run your program using a debugger, and step through the code. Put a watch on nVowels and then watch it count up -- when it becomes 4, you’ll at least know what’s causing it.