Pointers

Pages: 12
Hi,

Before, I've tried to understand C++, yet I didn't get very far with the pointers... I've started a new try, and now I'm getting the hang of it better.
However, one thing stuck me on this page:
http://www.cplusplus.com/doc/tutorial/pointers/

I understand, if you want to point to an int, the following would not work:
int * a = 35;
As the number you would assign would become the memory-address, and not the actual value. Assuming b is an ordinary int, this would work fine however:
int * a = &b;
as the memory-address of a would become the memory-address of b.

Till now I'm right, isn't it?

Yet, there is one piece of code:
char * terry = "hello";
Thinking in the same way as the int* above, I would suspect here I would be doing the same: The memory-address would become "hello". But this obviously isn't the case, is it?
Is there any reasonable explanation for this? And viewing from a greater perspective, are there more types where this occurs?

Thanks in advance,
Marco
"hello"

This is a string literal. The characters that make it up are hard-coded into the program, with a zero stuck on the end, and you get back a pointer to a const char (which is a numerical value, and that numerical value is the memory address of the h).

char* terry = "hello";
therefore says create a char pointer, called terry, and make it equal to this thing on the right. What's on the right? A pointer to a const char, so I'm making a pointer to a char equal to a pointer to a (const) char, which makes perfect sense.
Last edited on
Hi,

Perfectly clear! However, one problem:
1
2
3
4
5
6
  char* test = "Test";
  
  cout << &test << endl;
  cout << test << endl;
  cout << *test << endl;
  cout << *&test << endl;


Generates on my machine:

0x23ff3c
Test
T
Test


According to your explanation, test would have to be the pointer (memory address) pointing to the text "Test", isn't it? Put in another way, "Test" should return a memory address.
However, it seems &test does that. In that case, I would expect *&test to be the value of the byte at the memory address, in this case T, but it apparantly outputs Test.
Where am I going wrong here?
test is a char pointer.
&test is the address of a char pointer (not the value of that char pointer)
*&test is the contents of the address of a char pointer, which is the char pointer again.

So cout << *&test is cout << test, and when you pass a char pointer to a cout (as you did already in cout << test ) cout dereferences the char pointer and outputs the characters.

cout << &test does not give you the address of the first character in "Test". It gives you the address of the char pointer that points to the first character in "Test".

If you want to see the address of the first character of "Test", you will have to pass cout something other than a char*, as cout treats char* differently. Try this:

1
2
3
4
char* test = "Test";
int* t2 = (int*)test;

cout << t2;


According to your explanation, test would have to be the pointer (memory address) pointing to the text "Test", isn't it? Put in another way, "Test" should return a memory address.

To summarise, it does, but when you pass a char* to cout, cout doesn't output the char* - cout outputs what the char* points at, and all the following chars until it finds a zero.
Last edited on
Ah I understand. Is there a way to display whatever a variable actually holds, rather than what a function thinks it should display from it, such as in this case?
cout will output the value of an int*, rather than the int it points to , so cast a char* as an int* to get the value of it (this is some bad code, by the way):

1
2
3
char* test = "Test";
int* t2 = (int*)test;
cout << t2;


Ok, well most of it is clear to me now. Back to my test with output:

1
2
3
4
5
6
  char* test = "Test";
  
  cout << &test << endl;
  cout << test << endl;
  cout << *test << endl;
  cout << *&test << endl;



0x23ff3c
Test
T
Test


So test is actually a memory address/pointer, and for some reason (I guess a good one) 'cout test' outputs Test instead of the address. If using the address as actual address/pointer, *test gives us the logical result T.
However, in my perception &test should give an error as test is already a memory-address/pointer? Or is this a kind of 'pointer to pointer', as also explained in the tutorial?
Last edited on
Or is this a kind of 'pointer to pointer', as also explained in the tutorial?


Bingo. A pointer is just a variable, like any other. It takes up 4 bytes (or 8, depending on your PC) and it looks just like an int. It's just a number, and because it occupies memory, that memory has an address. You can make a pointer to any kind of variable, including a pointer.
for some reason (I guess a good one) 'cout test' outputs Test


Convenience. If you're coding in C++, sooner or later you're going to have to work with a C-string (i.e. an array of char, and you just have a pointer to the first). If you want to output that C-string, something like this would be a real pain:

1
2
3
4
5
6
7
char* variablePointerToChar = pointerToFirstCharInCString;
int lengthOfCstring = strlen(pointerToFirstCharInCString);
for (int i=0; i< lengthOfCstring; ++i)
{
  cout << *variablePointerToChar; // output the character I'm pointing at...
  variablePointerToChar++; // and move along one so that I can output the next one
}

There is a series of pages that explain pointers in C quite well. I think it's worth reading.

They start here: http://computer.howstuffworks.com/c20.htm or you can see the whole tutorial on one page here: http://computer.howstuffworks.com/c.htm/printable
cout deals with char pointers as if they point to C-Strings, referencing what a C-String points to directly just yields the first character of the string, because C++ thinks you want a character.

I'm also pretty sure the handling of different data types by cout has little to do with how C handles pointers. This is a C++ feature, surely?

@Veltas

I'm also pretty sure the handling of different data types by cout has little to do with how C handles pointers. This is a C++ feature, surely?


No you are wrong. Simply compare C and C++ output functions. For example C standard function puts outputs character arrays by accepting the argument as a pointer to character the same way as C++ standard operator << does exeplt that the puts append a new line character at the end of the output.


1
2
3
4
5
6
7
8
#include <iostream>
#include <cstdio>

int main()
{
   std::puts( "Hello World" );
   std:;cout << "Hello World\n";
}
What I mean to say is puts is a function that takes a char *, and cout takes a whole bunch of different types.

EDIT: To be more clear, the trouble seemed to be with understanding why different data types were handled completely differently based on type, and that's simply a feature of C++; specifically operator overloading the same operator multiple times.

EDIT2: To add more, it may seem strange to a C programmer that the operation that takes a char and outputs its ASCII, and then takes an address in the exact same form but rather than attempting to output the address as ASCII knows to handle it differently because it's a char *.
Last edited on
cout - is a stream that has many members funcions. And puts is also one of functoins that deal with the standard output stream. So I do not see the difference. The only difference is the names of functions. In C++ many output functions were substituted for the overloaded function operator <<.
Last edited on
The misunderstanding was to do with overloading, not pointers. Or at least I thought so.
As I think I get this discussion fairly well, I think I also get the concept of pointers and their usage with for example cout quite well.

Thanks thusfar anyways :) .

I just got another question when I read through the link provided by kbw. I have this piece of code:
1
2
3
4
5
6
7
8
9
10
11
12
#include <stdio.h>
#include <iostream>

using namespace std;

int main(){
    int *p;
    *p = 5;

   return 0;
}


The includes are not quite needed, but the problem is; this does not work, the program starts but crashes. What's the problem here, as I do not get any error from the editor?

(I'm using Dev-C++ by the way, are there maybe any better recommendations? ;) )
int *p;
So p is a pointer. what value does it have? No idea. You didn't give it a value. It will have some random value, so it will be pointing at some random piece of memory somewhere.

*p = 5;
And now you want to write the value 5 into that random memory somewhere. The OS is watching you, and notices you trying to write into memory that does not belong to you. It deals with this by segFaulting.

Why would you get an error in the editor?
Dunno, but I thought with int *p you implicitly allocate some memory for your int? But apparantly the pointer is 'nothing but air' until you assign an actual address to it?
In particular, for an int *p to be able to hold an int, you have to create another 'normal' int, to assign it's location to p?
Last edited on
1
2
3
4
5
6
int main()
{
    int *p;
    *p = 5;
    return 0;
}


Line 3 declares a variable p of type int*. p is not given an initial value.

Line 4 assigns 5 to the int that p points to.
As p is uninitialised, it could be pointing anywhere, you just don't know. Assigning 5, overwrites the memory it's pointing at.

So although the code has correct syntax, the result is undefined. Undefined for C/C++ programs usually means crash.

You could initiase it to point at something known.
1
2
3
4
5
6
7
int main()
{
    int a = 0;
    int *p = &a;
    *p = 5;
    return 0;
}

Last edited on
Dunno, but I thought with int *p you implicitly allocate some memory for your int?

No.

But apparantly the pointer is 'nothing but air' until you assign an actual address to it?

It's a complete, fully operational pointer, pointing to some random location.
Last edited on
Pages: 12