tags:

views:

409

answers:

11

Possible Duplicate:
Common Uses For Pointers?

I am still learning the basics of C++ but I already know enough to do useful little programs.

I understand the concept of pointers and the examples I see in tutorials make sense to me. However, on the practical level, and being a (former) PHP developer, I am not yet confident to actually use them in my programs.

In fact, so far I have not felt the need to use any pointer. I have my classes and functions and I seem to be doing perfectly fine without using any pointer (let alone pointers to pointers). And I can't help feeling a bit proud of my little programs.

Still, I am aware that I am missing on one of C++'s most important feature, a double edged one: pointers and memory management can create havoc, seemingly random crashes, hard to find bugs and security holes... but at the same time, properly used, they must allow for clever and efficient programming.

So: do tell me what I am missing by not using pointers.

What are good scenarios where using pointers is a must?
What do they allow you to do that you couldn't do otherwise?
In which way to they make your programs more efficient?

And what about pointers to pointers???

[Edit: All the various answers are useful. One problem at SO is that we cannot "accept" more than one answer. I often wish I could. Actually, it's all the answers combined that help to understand better the whole picture. Thanks.]

+7  A: 

I use pointers when I want to give a class access to an object, without giving it ownership of that object. Even then, I can use a reference, unless I need to be able to change which object I am accessing and/or I need the option of no object, in which case the pointer would be NULL.

PigBen
Pretty much the only reason I can think of.
GMan
This is a short version of the whole picture. The first line is exactly why you would use *references* rather than pointers. Pointers have to be used when references do not serve the purpose, which is a smaller subset.
David Rodríguez - dribeas
@David -- Good point. Answer updated.
PigBen
+2  A: 

A big use for pointers is dynamic sizing of arrays. When you don't know the size of the array at compile time, you will need to allocate it at run-time.

int *array = new int[dynamicSize];

If your solution to this problem is to use std::vector from the STL, they use dynamic memory allocation behind the scenes.

Jason Iverson
I've found that `std::vector` is often even simpler than a smart pointer. Having that stuff hidden behind the scenes is a powerful abstraction, once you understand how it all works. That's the problem - to understand why something is so wonderful, you have to understand the alternative as well.
Mark Ransom
Sorry but I have to -1 this. This is the *perfect* example of where pointers should no longer be used. `std:vector` is just better. Answers like this only obscure the places where pointers really are invaluable.
j_random_hacker
@j_random_hacker You can't generalize it away with a blanket statement stating that you should always use a std::vector. There will always be situations when the overhead of std::vector is unneeded. Not everyone works on the high level, some of us deal with a lot of low level implementations for optimizations on low memory hardware. I will admit that 98% of the time I use std::vector (or my own optimized version), but there are situations that I'd still use the "old school" way of doing it.
Jason Iverson
@Jason: Agreed it can be useful on about 2% of occasions for that, but the question asker is a C++ newbie and we should not be recommending using pointers for this bug-intensive approach when there are now safer alternatives AND other, better uses to which pointers can be put. (BTW remember the bulk of the overhead comes from the dynamic allocation itself and not from `std::vector` -- you would be better served writing an allocator and using `std::vector` anyway.)
j_random_hacker
@Jason: What overhead? You still shouldn't be in a position to `delete` something. If you claim overhead, that at the least just put it in a `unique_ptr`, which has none.
GMan
+2  A: 

There are several scenarios where pointers are required:

  • If you are using Abstract Base Classes with virtual methods. You can hold a std::vector and loop through all these objects and call a virtual method. This REQUIRES pointers.
  • You can pass a pointer to a buffer to a method reading from a file etc.
  • You need a lot of memory allocated on the heap.

It's a good thing to care about memory problems right from the start. So if you start using pointers, you might as well take a look at smart pointers, like boost's shared_ptr for example.

Philipp
Uggg.. smart pointers.. boost.. Ugh. I don't think smart pointers are a good place for people to start. Oh and not everyone can use boost. It pre-supposes STL. I loath STL because I can't use it, and it's on every last "do you know c++" test.
baash05
Smart pointers can save you a lot of headaches and make your code more expressive by telling the reader who is owning the object pointed to. If he can't use boost, he doesn't have to, but I suggested "he might take a look at it". So I don't think it's a bad adivice...
Philipp
@baash: I accidentally upvoted your comment. Use smart pointers, use SBRM/RAII, and wrap your resources, or you're not writing good code.
GMan
The problem with "smart" pointers is that there are a half-dozen different varieties of them, so every time you want a pointer you have to stop and think about what kind to use.
Gabe
@Gabe, if you're trying to program without thinking, you're using the wrong language. Or maybe the wrong profession.
Mark Ransom
I would concentrate on few important pointers (shared, scoped, weak). Then in fact this might be a good thing: If you don't use smart pointers you are not forced to think about "who is owning this pointer?" which might get you into memory leaks or double deleted objects! After using them for a while, this won't be a problem anymore.
Philipp
Mark: Every moment I spend thinking about how variables will be ref-counted is a moment I spend not thinking about my algorithm. Maybe I'm just not smart enough to use smart pointers.
Gabe
I keep it simple.. I create and I destroy. new and delete have always worked for me.. When I create, I just make sure all my closing branches clean up. It's insanely easy to do. I don't get why smart pointers are needed.. They might make something easy, easier, but I prefer simpler to easier.
baash05
GMan.. purposely upvoted your comment. The research value alone will make you far under "pointed" :)
baash05
A: 

You can use them for linked lists, trees, etc. They're very important data structures.

muntoo
Though you'd be using the linked list and tree. You mean use them to *implement* the container that's going to *manage* the structure that we're going to use.
GMan
+1  A: 

A pointer has a special value, NULL, that reference's won't. I use pointers wherever NULL is a valid and useful value.

ArunSaha
Boost has a couple of alternatives for objects that must contain a `null` state.
Mark Ransom
+3  A: 

If you haven't felt a need for pointers, I wouldn't spend a lot of time worrying about them until a need arises.

That said, one of the primary ways pointers can contribute to more efficient programming is by avoiding copies of actual data. For example, let's assume you were writing a network stack. You receive an Ethernet packet to be processed. You successively pass that data up the stack from the "raw" Ethernet driver to the IP driver to the TCP driver to, say, the HTTP driver to something that processes the HTML it contains.

If you're making a new copy of the contents for each of those, you end up making at least four copies of the data before you actually get around to rendering it at all.

Using pointers can avoid a lot of that -- instead of copying the data itself, you just pass around a pointer to the data. Each successive layer of the network stack looks at its own header, and passes a pointer to what it considers the "payload" up to the next higher layer in the stack. That next layer looks at its own header, modifies the pointer to show what it considers the payload, and passes it on up the stack. Instead of four copies of the data, all four layers work with one copy of the real data.

Jerry Coffin
+1  A: 

I just want to say that i rarely use pointers. I use references and stl objects (deque, list, map, etc).

A good idea is when you need to return an object where the calling function should free or when you dont want to return by value.

 List<char*>* fileToList(char*filename) { //dont want to pass list by value
 ClassName* DataToMyClass(DbConnectionOrSomeType& data) { 
 //alternatively you can do the below which doesnt require pointers
 void DataToMyClass(DbConnectionOrSomeType& data, ClassName& myClass) { 

Thats pretty much the only situation i use but i am not thinking that hard. Also if i want a function to modify a variable and cant use the return value (say i need more then one)

 bool SetToFiveIfPositive(int**v) {
acidzombie24
Return a smart pointer and the calling function won’t have to free it. Alternatively, in C++0x just return the `list` by value. It will be moved, not copied.
Nate
+1, prefer references and STL containers wherever possible.
j_random_hacker
@Nate: I never, ever had to use a smart pointer. Also smart pointers need regular pointers so i rather discuss that instead. You mean C++0x can return rvalue instead? yeah that would work. ATM we cant o that in most compilers which is unfortunate.
acidzombie24
+4  A: 

Pointers are commonly used in C++. Becoming comfortable with them, will help you understand a broader range of code. That said if you can avoid them that is great, however, in time as your programs become more complex, you will likely need them even if only to interface with other libraries.

  • Primarily pointers are used to refer to dynamically allocated memory (returned by new).

  • They allow functions to take arguments that cannot be copied onto the stack either because they are too big or cannot be copied, such as an object returned by a system call. (I think also stack alignment, can be an issue, but too hazy to be confident.)

  • In embedded programing they are used to refer to things like hardware registers, which require that the code write to a very specific address in memory.

  • Pointers are also used to access objects through their base class interfaces. That is if I have a class B that is derived from class A class B : public A {}. That is an instance of the object B could be accessed as if it where class A by providing its address to a pointer to class A, ie: A *a = &b_obj;

  • It is a C idiom to use pointers as iterators on arrays. This may still be common in older C++ code, but is probably considered a poor cousin to the STL iterator objects.

  • If you need to interface with C code, you will invariable need to handle pointers which are used to refer to dynamically allocated objects, as there are no references. C strings are just pointers to an array of characters terminated by the nul '\0' character.

Once you feel comfortable with pointers, pointers to pointers won't seem so awful. The most obvious example is the argument list to main(). This is typically declared as char *argv[], but I have seen it declared (legally I believe) as char **argv.

The declaration is C style, but it says that I have array of pointers to pointers to char. Which is interpreted as a arbitrary sized array (the size is carried by argc) of C style strings (character arrays terminated by the nul '\0' character).

Marc
+1 but it would be good to mention that references can do a lot of this work and are safer.
j_random_hacker
Thanks @j_random_hacker and everybody for commenting on the answers. Both answers and comments are useful. I'm still learning.
augustin
One clarification: C strings are terminated by the null \0 character, not the 0 character.
JRam930
@JRam930 Yes - I have updated to make that clearer based on your comment.
Marc
+1 for hardware registers.
acidzombie24
@j_random_hacker: Yes i agree. I was disappointed to see mention of pointers to use base class interfaces instead of references. Or not mentioning a user 'should' use stl for memory 'most of the time'. I actually have done a number of projects without a single pointer by using references and stl. No ugly code or hackorey needed.
acidzombie24
+1  A: 

What are good scenarios where using pointers is a must?
Interviews. Implement strcpy.

What do they allow you to do that you couldn't do otherwise?
Use of inheritance hierarchy. Data structures like Binary trees.

In which way to they make your programs more efficient?
They give more control to the programmer, for creating and deleting resources at run time.

And what about pointers to pointers???
A frequently asked interview question. How will you create two dimensional array on heap.

Manoj R
Considered -1ing, since the question is tagged C++ and no C++ programmer should have to implement `strcpy()`, but really that -1 belongs to the stupid interviewer. (The same *should* be true of creating a 2D heap array, but tragically this can't be done efficienctly < C++0x.)
j_random_hacker
+6  A: 

This question has been asked on SO before. My answer from there:

I use pointers about once every six lines in the C++ code that I write. Off the top of my head, these are the most common uses:

  • When I need to dynamically create an object whose lifetime exceeds the scope in which it was created.
  • When I need to allocate an object whose size is unknown at compile time.
  • When I need to transfer ownership of an object from one thing to another without actually copying it (like in a linked list/heap/whatever of really big, expensive structs)
  • When I need to refer to the same object from two different places.
  • When I need to slice an array without copying it.
  • When I need to use compiler intrinsics to generate CPU-specific instructions, or work around situations where the compiler emits suboptimal or naive code.
  • When I need to write directly to a specific region of memory (because it has memory-mapped IO).
Crashworks
That last point is only relevant with embedded or driver programming, and could easily be replaced with a reference. Otherwise it's a nice comprehensive list.
Mark Ransom
There are cases where drivers or operating systems sometimes just give you naked addresses for things, and I don't know any way to to seat a reference to an arbitrary address. For example, the OS function to get the destination for sound data on one popular game console literally has the prototype `uint64 AudioGetPortReadAddr( uint32 portNumber );`
Crashworks
+1 in general, but two concerns: It seems from your second line that pointers are the most common construct in the language (1/6 of the lines) while in many domains you can write perfectly good code without actually having a single pointer. When you need to refer to the same object from two places you have to decide between a pointer or a reference, and the later should be preferred if possible.
David Rodríguez - dribeas
... an example where a pointer must be used in place of a reference is this: `int a,b,*c = c = ` This cannot be implemented with a reference, as the reference would be bound to `a` at definition time and could not be *reseated* to refer to `b` later on. To complete the answer, one extra situation where pointers are a used is when passing optional arguments to a function, as pointers can be null, but references/values (of non pointer type) cannot.
David Rodríguez - dribeas
As David pointed out, the times I find myself using a pointer is often when I need to reseat (good term) the pointer in the course of decision logic in a function. The other situation, which also involves reseating, is when pointer arithmetic is being performed on an array of items. Like it or not, not everything is implemented in vectors and iterators.
Dan
The first point, i.e., "When I need to dynamically create an object whose lifetime exceeds the scope in which it was created.", is the main reason why I have to use (smart) pointers instead of reference.
EXP0
A: 

In general, pointers are useful as they can hold the address of a chunk of memory. They are especially useful in some low level drivers where they are efficiently used to operate on a piece of memory byte by byte. They are most powerful invention that C++ inherits from C.

As to pointer to pointer, here is a "hello-world" example showing you how to use it.

#include <iostream>

void main()
{
    int i = 1;
    int j = 2;

    int *pInt = &i;                 // "pInt" points to "i"

    std::cout<<*pInt<<std::endl;    // prints: 1

    *pInt = 6;                      // modify i, i = 6

    std::cout<<i<<std::endl;        // prints: 6

    int **ppInt = &pInt;            // "ppInt" points to "pInt"

    std::cout<<**ppInt<<std::endl;  // prints: 6

    **ppInt = 8;                    // modify i, i = 8

    std::cout<<i<<std::endl;        // prints: 8

    *ppInt = &j;                    // now pInt points to j

    *pInt = 10;                     // modify j, j = 10

    std::cout<<j<<std::endl;        // prints: 10
}

As we see, "pInt" is a pointer to integer which points to "i" at the beginning. With it, you can modify "i". "ppInt" is a pointer to pointer which points to "pInt". With it, you can modify "pInt" which happens to be an address. As a result, "*ppInt = &j" makes "pInt" points to "j" now. So we have all the results above.

Eric