C++ Pointer Questions

Hi!
First of all, this is my first thread here.

Right now, I'm in the process of learning C++. Everything was going smoothly until I hit 'pointers'.

Now, I know some basics of pointers but there were some things I didn't understand.

1. Is dereferencing a pointer the same as declaring/initializing a data-type?

2. Pointers are fast due to fact that they use memory addresses. Why are they fast just because they use memory addresses?
For example, if we were sorting an array, sorting via pointers would be much faster than accessing the elements themselves... Why?

3. In the case of a user-defined data-type (such as a class), does using the keyword 'new' create a new object? How? If it doesn't, then what does it do?

4. I've seen some graphic and multimedia libraries (for e.g SDL) use pointers for their own data-types (for example in the case of SDL, there's SDL_Surface*). So what does this tell the compiler to do? What happens when we declare this? I've seen DirectX use similar things...

Does it tell us that this particular data-type has been declared/setup somewhere in the memory and the only way we can use this is by just declaring a pointer to this data-type? Will it work in the same way if we declared an object of this data-type? If so, how?
Also, is this efficient if we don't know the actual variable rather we know its pointer?

5. Array of pointer to objects would be efficient, because of the fact that we can create new objects whenever we need them.
For example
1
2
3
4
class* object[10];
//loop
object[i] = new object;
print object[i];

How does the above code differ from
1
2
3
class object[10];
//loop
print object[i];

The code, of course, is not proper; I just wanted to convey my idea.

The point is, both arrays have been given a constant limit. How can this be flexible and efficient? What's the workaround to this? What can be done so as to make ONE more object than the given limit?


Any help would be appreciated... Thanks in advance... :)
1. Is dereferencing a pointer the same as declaring/initializing a data-type?
No.
Declaring the pointer is telling the compiler about it.
Initializing the pointer is assinging it an initial value.
Dereferencing the pointer is looking at what it's pointing to.

2. Pointers are fast due to fact that they use memory addresses.
Faster than what? I wouldn't necessarily agree with the statement.
Last edited on
1. Is dereferencing a pointer the same as declaring/initializing a data-type?

Not quite; but there's one thing in common: if you have a variable (aka named object), using its name in an expression is equivalent to dereferencing a pointer to it in an expression:

Given
1
2
int n = 1;
int* p = &n;

n and *p are the same:
1
2
int& r1 = n; // reference to n
int& r2 = *p; // also a reference to n 


2. Pointers are fast due to fact that they use memory addresses. Why are they fast just because they use memory addresses?
Pointers are slow due to an extra level of indirection and are often additionally burdened by runtime checks. This really depends on exact context.

if we were sorting an array, sorting via pointers would be much faster than accessing the elements themselves... Why?

Array of what? Array of vectors would be much faster to sort directly. Array of arrays, or other slow-to-swap objects would be slow, and if you can build an array of pointers to those original arrays, sorting it indirectly would be faster. It's not very common.

The point is, both arrays have been given a constant limit. How can this be flexible and efficient?
vector<class> object(10);
Last edited on
syndrome wrote:
1. Is dereferencing a pointer the same as declaring/initializing a data-type?

No. You declare and initialize a pointer like you would any other data type. Only difference is a pointer is initialized with the address of another variable.
1
2
int a = 10;  //Just an int, value of 10
int *b = &a; //Now this a pointer to an int, with value of the address of a 


When you dereference a pointer, what you are doing is saying "Hey, I have this address. Now what's in that address?".

1
2
std::cout << *b; //Will output 10
std::cout << b; //Will output some hex value that represents the address of a 


syndrome wrote:
2. Pointers are fast due to fact that they use memory addresses. Why are they fast just because they use memory addresses?
For example, if we were sorting an array, sorting via pointers would be much faster than accessing the elements themselves... Why?


They're more efficient. Not always faster. This example, they aren't faster because really when accessing an array by index what you're doing is using a pointer. You just didn't know it :) Pointers are more efficient because they are only 4 or 8 bytes in length. If you're passing around large data structures, it is much better to pass 4 bytes than it would be to pass 50 bytes. You also get past having to use a copy constructor, which takes time also.

syndrome wrote:
3. In the case of a user-defined data-type (such as a class), does using the keyword 'new' create a new object? How? If it doesn't, then what does it do?


You can use new for primitive types also. What new does is it creates an object on the heap for you. This requires a call to the OS. It will also initialize the object for you using the default constructor (if it doesn't have one, it won't work).


syndrome wrote:
4. I've seen some graphic and multimedia libraries (for e.g SDL) use pointers for their own data-types (for example in the case of SDL, there's SDL_Surface*). So what does this tell the compiler to do? What happens when we declare this? I've seen DirectX use similar things...


You have to remember a user-defined data type is just a data type. So you can have pointers to it like any other. They work just the same way as any other pointer.


Does it tell us that this particular data-type has been declared/setup somewhere in the memory and the only way we can use this is by just declaring a pointer to this data-type? Will it work in the same way if we declared an object of this data-type? If so, how?
Also, is this efficient if we don't know the actual variable rather we know its pointer?


No. You're thinking about this wrong. Pointers aren't complicated (but they give people trouble still). All they do is store an address. An int stores a integer value, a double stores a floating-point value, etc. A pointer stores an address.

syndrome wrote:
5. Array of pointer to objects would be efficient, because of the fact that we can create new objects whenever we need them.
For example...


The second example will initialize all the objects for you using their default constructor. The first example is just a bunch of pointers which will point to nothing until you give them something to point, like you do using new. The former has the benefit of size. It's going to be much smaller than the second, but it also requires lots of calls to the OS to get heap space for all those objects. So while the array itself is stored on the stack, what the array is pointing to is all in heap space. The second example has all of the objects in stack space.
Hi, thanks for all the replies (and very very sorry for my late reply [-_-] )
@ResidentBiscuit
No. You're thinking about this wrong. Pointers aren't complicated (but they give people trouble still). All they do is store an address. An int stores a integer value, a double stores a floating-point value, etc. A pointer stores an address.

So a pointer to (say) SDL_Surface means what? Does it mean that it stores an address big enough to hold an object of the type SDL_Surface? So, why use a pointer to this object type instead of just declaring and initializing this object? What does is say in this example?

@ResidentBiscuit
Pointers are more efficient because they are only 4 or 8 bytes in length. If you're passing around large data structures, it is much better to pass 4 bytes than it would be to pass 50 bytes. You also get past having to use a copy constructor, which takes time also.

But I thought that pointers used to hold an address big enough of the data-type used...?

@ResidentBiscuit
You can use new for primitive types also. What new does is it creates an object on the heap for you. This requires a call to the OS. It will also initialize the object for you using the default constructor (if it doesn't have one, it won't work).

Can you please explain this?

@ResidentBiscuit
They're more efficient. Not always faster. This example, they aren't faster because really when accessing an array by index what you're doing is using a pointer. You just didn't know it :) Pointers are more efficient because they are only 4 or 8 bytes in length. If you're passing around large data structures, it is much better to pass 4 bytes than it would be to pass 50 bytes. You also get past having to use a copy constructor, which takes time also.

Can you give me another example, please?

@kbw 2. Pointers are fast due to fact that they use memory addresses.
Faster than what?I wouldn't necessarily agree with the statement.

Can you please explain this?

Again, thanks for all the replies! :)
Thank you very much...!
syndrome wrote:
So a pointer to (say) SDL_Surface means what? Does it mean that it stores an address big enough to hold an object of the type SDL_Surface? So, why use a pointer to this object type instead of just declaring and initializing this object? What does is say in this example?

A pointer will always be 4 bytes (or 8 on a 64 bit machine). Doesn't matter what it points to. The only reason we have types on pointers is so you can properly do pointer arithmetic. The reason for these sizes is that it only takes a certain number of bits to address something. On a 32 bit system, a program can address 4 bytes of memory (32 / 8 = 4). Since objects reside in their own place in memory all a pointer needs to do is store the starting address of that object.

syndrome wrote:
Can you please explain this?

Well which part? There were a few things described there.

syndrome wrote:
Can you give me another example, please?

Say you have a class that consists of several objects of other classes. If you were to pass this by value, the copy constructor will be invoked. This will mean every object that class has has to be copied. What if these objects have other objects also? Then these also have to invoke the copy constructor. As you can see, this can quickly lead to tons of function calls just to copy this object over. A pointer gets around this because you just pass the address of the object and that's it.
So a pointer to (say) SDL_Surface means what? Does it mean that it stores an address big enough to hold an object of the type SDL_Surface?

Not exactly. A pointer is just a number. It's a number that represents an address in memory. Addresses are just numbers - they just indicate a location in memory. Think of it like the address of a house - it's just a number that tells the program where to look in memory for some data. You wouldn't need a piece of paper the size of your house to write down the number of your house, and you wouldn't need something the size of an SDL_Surface object to store the address of that object in memory.

The type of a pointer tells the program how to interpret the data it finds at that address.

So, why use a pointer to this object type instead of just declaring and initializing this object? What does is say in this example?

There are many reasons. One of the principal ones is dynamic allocation of objects on the heap.

When you simply declare an object, the memory for that object is on the stack. The object only exists within the scope where it is declared - e.g. within that function, or code block, or class, or whatever. When the code execution reaches the end of that scope, the stack unwinds, and the object is destroyed.

Dynamic allocation, on the other hand, allocates the memory for the object on the heap. This means that it persists until you free it. When you dynamically allocate memory using new, it returns the address of the memory. You can then pass that address around as a pointer, knowing that the memory set aside for that object will remain intact until it is explicitly deleted by the code.

Another use for pointers is to get around the issue that C functions pass arguments by value, not reference. You can use them in C++ too, although C++ adds references to the language which are a cleaner way to do this.

There are many other uses for pointers too, but, frankly, any halfway decent textbook should cover this stuff, and there are probably hundreds of tutorials on the net too, so there's no point any of us typing it out again.
Thanks for the replies, again...!

A pointer will always be 4 bytes (or 8 on a 64 bit machine). Doesn't matter what it points to. The only reason we have types on pointers is so you can properly do pointer arithmetic. The reason for these sizes is that it only takes a certain number of bits to address something. On a 32 bit system, a program can address 4 bytes of memory (32 / 8 = 4). Since objects reside in their own place in memory all a pointer needs to do is store the starting address of that object.


Not exactly. A pointer is just a number. It's a number that represents an address in memory. Addresses are just numbers - they just indicate a location in memory. Think of it like the address of a house - it's just a number that tells the program where to look in memory for some data. You wouldn't need a piece of paper the size of your house to write down the number of your house, and you wouldn't need something the size of an SDL_Surface object to store the address of that object in memory.


Wow!! Never even thought about that...!

That pretty much solves my dilemma regarding pointers...

Now, to sum it up, I would like to summarize:-

- Pointers are used to hold addresses of ANY data-type, REGARDLESS of their size.
- Pointers are just 4 or 8 bytes in size (depending upon the machine: 32 or 64 bit).
- Pointer arithmetic depends upon the size of the of the data-type of which the pointer points to.
- Pointers are used for dynamic memory allocation for maintaining the scope of a specific data-type.
- Pointers are used for passing the reference values of variables in functions instead of passing them by their values.
- Pointers should always be initialized.


Two final things:-
1. Are the above points right?
2. Can a pointer to a data-type, declared/initialized inside a function or a class, be accessed outside of the function or class in which it was declared/initialized, as stated in the reply above:-
Dynamic allocation, on the other hand, allocates the memory for the object on the heap. This means that it persists until you free it. When you dynamically allocate memory using new, it returns the address of the memory. You can then pass that address around as a pointer, knowing that the memory set aside for that object will remain intact until it is explicitly deleted by the code.
Looks like you got it. As for the second question, if the pointer is in the scope of a function, once that function exits you lose the pointer. A pointer follows the same scoping rules as any other variable.
Are the above points right?

Yes. Although I'd re-write the final one as "Variables and objects of any kind should always be initialised." :)

Can a pointer to a data-type, declared/initialized inside a function or a class, be accessed outside of the function or class in which it was declared/initialized, as stated in the reply above:

In this regard, you treat the pointer as any other variable which contains a number. You can pass it into a function, return it from a function, copy the value from one variable to another, etc.

If you're asking about the contents of the memory at the address that the pointer is set to, then that depends. If you dynamically allocate the memory on the heap, then that memory remains allocated until something in the code deletes it. However, if you choose to store the address of something else in that pointer, then you need to be aware of how long the data there is likely to remain valid.

Think back to the house analogy: if you buy some land and build a house on it, then you can give the address of the house to people, and you know that when they come looking for your house, they'll find it. You own that house, and you know that it'll be there as long as you want it to be.

If you write down the address of a house that somebody else has built on their land, then if you come back in 6 months, you might find that house still standing, or you might find that the owner's knocked it down and it no longer exists.

If you write down the address of a bit of land that someone's parked a mobile home on, you can be pretty sure that if you come back to that address in a few weeks, it won't be there any more.

The key thing is - just because you've written down the address, doesn't mean that the house will always be there. The paper won't magically burn up if the house is demolished. Nor will the house vanish just because you tear up the bit of paper with the address on it. And just because you write down an address on a bit of paper, it won't magically cause a house to build itself on that spot - someone needs to actually build it.

So it is with pointers. Your pointer might contain an address in memory, but you'll need to actually allocate and initialise the data at that address. You'll need to understand the circumstances under which that memory still contains the data you think is there, and the circumstances under which it will get thrown away.

One particular thing to be careful about is using pointers to objects on the stack, i.e. that have been declared and initialised in the normal way. When the object falls out of scope, the memory will be released and the data there will no longer be valid. If, however, you've kept the address of that object beyond this point, then don't attempt to try and access the data it points to - because it will be gone. The mobile home will have moved on, leaving an empty plot :)

Again, there will be plenty of material out there, online and in textbooks, that will explore this more thoroughly.
Last edited on
I thank(and salute) you all for your replies! :)
Topic archived. No new replies allowed.