This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How do pointer to pointers work in C?
Hello,
Altough I think I passed the newbie phase in programming I still have some questions that somehow I can't find them explained. Yes, there are plenty of "how to"s overthere but almost always nobody explains why and/or when one technique is useful.
In my case I have discovered that in some cases a pointer to a pointer is used in C++. Is not a pointer to an object enough? Which are the benefits? Where or when should be used a pointer to a pointer? I feel little bit desorientated in this matter.
I hope time experienced expert could respond to this concerns that hopefully is shared by other no so experienced programers. ;-)
Thank you everyone.
Julen.
Well, it is somehow hard to answer to such a general question.
First answer of a C++ programmer will certainly be : Do not use pointers in C++ ! As you have a lot of safer ways to handle problems than pointers, one of your goal will be to avoid them in the first place :)
So pointers to pointers are seldom used in C++. They are mainly used in C. First, because in C, strings are "char*" so when you need a "pointer to a C string" you end with a "char**". Second, as you do not have references in C, when you need to have a function that modify a pointer or that give a pointer as an output value, you need to give a pointer to a pointer parameter. You typically find that in functions that allocate memory, as they give you a pointer to the allocated memory.
If you go the C++ way, try to avoid pointers, you usually have better ways.
my2c
In C, an argument is passed to a function that changes it, through a pointer. You will see the same with C++ for old or legacy code (int main(int argc, char** argv)) , for code that will be accessed from C (COM / XPCOM) or with code that was written by someone used to C (or the C style).
From a "purely C++" standpoint, using pointer to pointer is in most situations a sign of poor coding style, as most situations that require a ** construct can (and should) be refactored to use safer alternatives (like std:: containers, or *& parameters).
I can think of two use cases.
One is arrays as inherited from C. Arrays automatically decay to pointers to their first elements in many cases. If you happen to have an array of pointers, you get a pointer to a pointer for that.
(Something similar can happen when you have a std::vector of pointers, BTW: A pointer is a perfect random access iterator and I have indeed seen std lib implementations using pointers for std::vector<>::iterator. For a std::vector of pointers, v.begin() would return a pointer to a pointer.)
The other is for function arguments. For function arguments, taking something per pointer indicates that callers might call the function even if they don't have an object to pass in; they can pass in NULL then. (Otherwise why take a pointer instead of a reference? See here for more details on this).
Taking a non-const reference to a pointer would indicate that the called function might assign a new address to that pointer.
So taking a pointer to a pointer would indicate that the function might assign a new address to a pointer, if the caller passes in a pointer to it, but is callable with NULL as well.
For example:
void f(int** ppi);
void g(int i);
void h()
{
f(NULL); // call `f()` only for its side-effects
int* pi = NULL;
f(&pi); // call `f()` and get some object in *pi
if(pi)
g(*pi); // use result
}
Where or when should be used a pointer to a pointer?
In a function that optionally may return pointer to caller, if the caller requests that. Frequently used by system APIs, some COM objects, etc.
int f(void** p = 0){
//.......
}
If caller provides p, then function passes pointer through p. If caller doesn't provide p, then no pointer is returned. May be useful for debugging purposes in certain situations.
Which are the benefits?
The question is too broad. Look, it is a VERY simple technique without some kind of mysterious benefits. You use it when you have to. That's all. There is no hidden meaning and no secret advantages of this concept - it is equivalent to asking "what are benefits of using letter \"e\" in english language".
Pointers to pointers have most relevance in C. Seldomly, you need them in C++. There you can work with containers from the std lib or with references.
There are two popular use cases in C though:
An array of pointers, most prominently used as argv to main(): the pointer gives the address to the array of argument strings (type char*). In C, the [] operators work on pointers to anything as pointers to anything are seen as an equivalent to arrays.
A function argument denoting a place where to store the address of something. Use case: In C, the return value is often used for error handling or state information. Arguments are used for carrying the payload. One example: A function "returns" an address to newly allocated memory, but using an argument. You give the function a pointer to the pointer that should afterwards point to the data. The function overwrites that space and for that, it needs a pointer to a pointer.
You only use them when employing manual memory management, something that's rare as hell in C++, therefore they're pretty useless. Even regular pointers are of questionable value in the majority of scenarios.
There're actually two use cases.
First, is when you call a function that has to return more than one value, some of which, are pointers. Then, you would provide her with an address of a pointer, so it could fill in the pointed pointer:
int *p1 = 0, *p2 = 0, *p3 = 0;
multi_malloc(&p1, &p2, &p3); // Allocates three pointers
Second is when you want to do sparse 2d arrays:
int main(int argc, char **argv)
This is a pointer to pointer. argv[i] is a pointer to char. This way, argv[i][j] is a char j in row i.
You will be happy to hear that there're nearly zero uses for pointer to pointer to pointer. int ***p; is almost never useful.
Related
I've been told that the following is bad code because z_strings is already a char array. However I don't really know much C++ so I don't really know what the usage is doing or why it would be wrong. Can somebody offer an explanation?
Declaration: char z_strings[3];
Usage: MyFunction(myints, (char**)&z_strings, another_int_arg);
Definition of MyFunction: void MyFunction(int* my_ints, char** z_strings, int another_int_arg)
For context, this is a coworker's "code review" code which is intentionally broken; he was using it to ask interview candidates to fix the bad code. However this coworker has actually left the company and the only notes say that it's a bad cast, and I'm trying to figure out some more details about why because I'm curious.
I removed context I thought was irrelevant, but for the full context MyFunction is actually GetPowers(p_int, (char**)&z_strings, 3); p_int will be an array like [2,3,4] and z_strings will be populated with values like ['Hundreds','Thousands','Ten Thousands'], in other words this function translates numerical powers into English equivalents.
Unlike the widespread and erroneously taught belief, arrays are not pointers. They may decay into pointers in most contexts, but the address-of operator is not one of those contexts.
If the type of z_strings is char[3], then the type of &z_strings is char (*)[3]. It is a pointer to an array of three characters. And a pointer to an array is not compatible with a pointer to a pointer.
That's what's wrong with your cast. As for how to fix it, with the little context you've shown, the obvious solution is to introduce an actual pointer:
char *p_z_strings = z_strings; //decay here
MyFunction(myints, &p_z_strings , another_int_arg); // no cast; exact match
With the added context you provided, the "obvious" solution is now rather glaringly incorrect. There's still a few details missing, but if we are working under the assumption that GetPowers will do the allocation for the new strings, we do not need additional variables:
char* z_strings[3]; // Now we have an array of pointers
GetPowers(p_int, z_strings, 3); // It decays into a pointer to a pointer
// GetPowers populates it
The cast is bad, because it shuts up the compiler, without fixing the code.
The real fix might be using the proper array, which could be (as the function argument type suggests) an array of pointers, e.g.
char *z_strings[3];
Now you can call the function without any cast at all:
MyFunction(myints, z_strings, another_int_arg);
In C and C++ an array 'decays' to a pointer when the identifier is used as an argument to a function that expects a pointer. This means that if you have a function that takes a char* (C and common C++ form of a string argument) then you can just pass it a char array and no casting is required.
In your example, you are casting to a char** which is a pointer to a pointer to a char. This suggests the function expects to change what a char* argument points to and this is not something that makes sense with an array argument. Without knowing more context here it's hard to give a more specific answer to your question though. It's also possible that a char** argument could be intended to be an array of strings (in which case you would expect an additional array size argument) but without seeing what MyFunction() is intended to do it's hard to say.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 9 years ago.
I know this is a really basic question, but I've just started with some basic C++ programming after coding a few projects with high-level languages.
Basically I have three questions:
Why use pointers over normal variables?
When and where should I use pointers?
How do you use pointers with arrays?
Why use pointers over normal variables?
Short answer is: Don't. ;-) Pointers are to be used where you can't use anything else. It is either because the lack of appropriate functionality, missing data types or for pure perfomance. More below...
When and where should I use pointers?
Short answer here is: Where you cannot use anything else. In C you don't have any support for complex datatypes such as a string. There are also no way of passing a variable "by reference" to a function. That's where you have to use pointers. Also you can have them to point at virtually anything, linked lists, members of structs and so on. But let's not go into that here.
How do you use pointers with arrays?
With little effort and much confusion. ;-) If we talk about simple data types such as int and char there is little difference between an array and a pointer.
These declarations are very similar (but not the same - e.g., sizeof will return different values):
char* a = "Hello";
char a[] = "Hello";
You can reach any element in the array like this
printf("Second char is: %c", a[1]);
Index 1 since the array starts with element 0. :-)
Or you could equally do this
printf("Second char is: %c", *(a+1));
The pointer operator (the *) is needed since we are telling printf that we want to print a character. Without the *, the character representation of the memory address itself would be printed. Now we are using the character itself instead. If we had used %s instead of %c, we would have asked printf to print the content of the memory address pointed to by 'a' plus one (in this example above), and we wouldn't have had to put the * in front:
printf("Second char is: %s", (a+1)); /* WRONG */
But this would not have just printed the second character, but instead all characters in the next memory addresses, until a null character (\0) were found. And this is where things start to get dangerous. What if you accidentally try and print a variable of the type integer instead of a char pointer with the %s formatter?
char* a = "Hello";
int b = 120;
printf("Second char is: %s", b);
This would print whatever is found on memory address 120 and go on printing until a null character was found. It is wrong and illegal to perform this printf statement, but it would probably work anyway, since a pointer actually is of the type int in many environments. Imagine the problems you might cause if you were to use sprintf() instead and assign this way too long "char array" to another variable, that only got a certain limited space allocated. You would most likely end up writing over something else in the memory and cause your program to crash (if you are lucky).
Oh, and if you don't assign a string value to the char array / pointer when you declare it, you MUST allocate sufficient amount of memory to it before giving it a value. Using malloc, calloc or similar. This since you only declared one element in your array / one single memory address to point at. So here's a few examples:
char* x;
/* Allocate 6 bytes of memory for me and point x to the first of them. */
x = (char*) malloc(6);
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* Delete the allocation (reservation) of the memory. */
/* The char pointer x is still pointing to this address in memory though! */
free(x);
/* Same as malloc but here the allocated space is filled with null characters!*/
x = (char *) calloc(6, sizeof(x));
x[0] = 'H';
x[1] = 'e';
x[2] = 'l';
x[3] = 'l';
x[4] = 'o';
x[5] = '\0';
printf("String \"%s\" at address: %d\n", x, x);
/* And delete the allocation again... */
free(x);
/* We can set the size at declaration time as well */
char xx[6];
xx[0] = 'H';
xx[1] = 'e';
xx[2] = 'l';
xx[3] = 'l';
xx[4] = 'o';
xx[5] = '\0';
printf("String \"%s\" at address: %d\n", xx, xx);
Do note that you can still use the variable x after you have performed a free() of the allocated memory, but you do not know what is in there. Also do notice that the two printf() might give you different addresses, since there is no guarantee that the second allocation of memory is performed in the same space as the first one.
One reason to use pointers is so that a variable or an object can be modified in a called function.
In C++ it is a better practice to use references than pointers. Though references are essentially pointers, C++ to some extent hides the fact and makes it seem as if you are passing by value. This makes it easy to change the way the calling function receives the value without having to modify the semantics of passing it.
Consider the following examples:
Using references:
public void doSomething()
{
int i = 10;
doSomethingElse(i); // passes i by references since doSomethingElse() receives it
// by reference, but the syntax makes it appear as if i is passed
// by value
}
public void doSomethingElse(int& i) // receives i as a reference
{
cout << i << endl;
}
Using pointers:
public void doSomething()
{
int i = 10;
doSomethingElse(&i);
}
public void doSomethingElse(int* i)
{
cout << *i << endl;
}
Pointers allow you to refer to the same space in memory from multiple locations. This means that you can update memory in one location and the change can be seen from another location in your program. You will also save space by being able to share components in your data structures.
You should use pointers any place where you need to obtain and pass around the address to a specific spot in memory. You can also use pointers to navigate arrays:
An array is a block of contiguous memory that has been allocated with a specific type. The name of the array contains the value of the starting spot of the array. When you add 1, that takes you to the second spot. This allows you to write loops that increment a pointer that slides down the array without having an explicit counter for use in accessing the array.
Here is an example in C:
char hello[] = "hello";
char *p = hello;
while (*p)
{
*p += 1; // increase the character by one
p += 1; // move to the next spot
}
printf(hello);
prints
ifmmp
because it takes the value for each character and increments it by one.
Pointers are one way of getting an indirect reference to another variable. Instead of holding the value of a variable, they tell you its address. This is particularly useful when dealing with arrays, since using a pointer to the first element in an array (its address) you can quickly find the next element by incrementing the pointer (to the next address location).
The best explanation of pointers and pointer arithmetic that I've read is in K & R's The C Programming Language. A good book for beginning learning C++ is C++ Primer.
Let me try and answer this too.
Pointers are similar to references. In other words, they're not copies, but rather a way to refer to the original value.
Before anything else, one place where you will typically have to use pointers a lot is when you're dealing with embedded hardware. Maybe you need to toggle the state of a digital IO pin. Maybe you're processing an interrupt and need to store a value at a specific location. You get the picture. However, if you're not dealing with hardware directly and are just wondering about which types to use, read on.
Why use pointers as opposed to normal variables? The answer becomes clearer when you're dealing with complex types, like classes, structures and arrays. If you were to use a normal variable, you might end up making a copy (compilers are smart enough to prevent this in some situations and C++11 helps too, but we'll stay away from that discussion for now).
Now what happens if you want to modify the original value? You could use something like this:
MyType a; //let's ignore what MyType actually is right now.
a = modify(a);
That will work just fine and if you don't know exactly why you're using pointers, you shouldn't use them. Beware of the "they're probably faster" reason. Run your own tests and if they actually are faster, then use them.
However, let's say you're solving a problem where you need to allocate memory. When you allocate memory, you need to deallocate it. The memory allocation may or may not be successful. This is where pointers come in useful - they allow you to test for the existence of the object you've allocated and they allow you to access the object the memory was allocated for by de-referencing the pointer.
MyType *p = NULL; //empty pointer
if(p)
{
//we never reach here, because the pointer points to nothing
}
//now, let's allocate some memory
p = new MyType[50000];
if(p) //if the memory was allocated, this test will pass
{
//we can do something with our allocated array
for(size_t i=0; i!=50000; i++)
{
MyType &v = *(p+i); //get a reference to the ith object
//do something with it
//...
}
delete[] p; //we're done. de-allocate the memory
}
This is the key to why you would use pointers - references assume the element you're referencing exists already. A pointer does not.
The other reason why you would use pointers (or at least end up having to deal with them) is because they're a data type that existed before references. Therefore, if you end up using libraries to do the things that you know they're better at, you will find that a lot of these libraries use pointers all over the place, simply because of how long they've been around (a lot of them were written before C++).
If you didn't use any libraries, you could design your code in such a way that you could stay away from pointers, but given that pointers are one of the basic types of the language, the faster you get comfortable using them, the more portable your C++ skills would be.
From a maintainability point of view, I should also mention that when you do use pointers, you either have to test for their validity and handle the case when they're not valid, or, just assume they are valid and accept the fact that your program will crash or worse WHEN that assumption is broken. Put another way, your choice with pointers is to either introduce code complexity or more maintenance effort when something breaks and you're trying to track down a bug that belongs to a whole class of errors that pointers introduce, like memory corruption.
So if you control all of your code, stay away from pointers and instead use references, keeping them const when you can. This will force you to think about the life times of your objects and will end up keeping your code easier to understand.
Just remember this difference: A reference is essentially a valid pointer. A pointer is not always valid.
So am I saying that its impossible to create an invalid reference? No. Its totally possible, because C++ lets you do almost anything. It's just harder to do unintentionally and you will be amazed at how many bugs are unintentional :)
Here's a slightly different, but insightful take on why many features of C make sense: http://steve.yegge.googlepages.com/tour-de-babel#C
Basically, the standard CPU architecture is a Von Neumann architecture, and it's tremendously useful to be able to refer to the location of a data item in memory, and do arithmetic with it, on such a machine. If you know any variant of assembly language, you will quickly see how crucial this is at the low level.
C++ makes pointers a bit confusing, since it sometimes manages them for you and hides their effect in the form of "references." If you use straight C, the need for pointers is much more obvious: there's no other way to do call-by-reference, it's the best way to store a string, it's the best way to iterate through an array, etc.
One use of pointers (I won't mention things already covered in other people's posts) is to access memory that you haven't allocated. This isn't useful much for PC programming, but it's used in embedded programming to access memory mapped hardware devices.
Back in the old days of DOS, you used to be able to access the video card's video memory directly by declaring a pointer to:
unsigned char *pVideoMemory = (unsigned char *)0xA0000000;
Many embedded devices still use this technique.
In large part, pointers are arrays (in C/C++) - they are addresses in memory, and can be accessed like an array if desired (in "normal" cases).
Since they're the address of an item, they're small: they take up only the space of an address. Since they're small, sending them to a function is cheap. And then they allow that function to work on the actual item rather than a copy.
If you want to do dynamic storage allocation (such as for a linked-list), you must use pointers, because they're the only way to grab memory from the heap.
Pointers are important in many data structures whose design requires the ability to link or chain one "node" to another efficiently. You would not "choose" a pointer over say a normal data type like float, they simply have different purposes.
Pointers are useful where you require high performance and/or compact memory footprint.
The address of the first element in your array can be assigned to a pointer. This then allows you to access the underlying allocated bytes directly. The whole point of an array is to avoid you needing to do this though.
One way to use pointers over variables is to eliminate duplicate memory required. For example, if you have some large complex object, you can use a pointer to point to that variable for each reference you make. With a variable, you need to duplicate the memory for each copy.
In C++, if you want to use subtype polymorphism, you have to use pointers. See this post: C++ Polymorphism without pointers.
Really, when you think about it, this makes sense. When you use subtype polymorphism, ultimately, you don't know ahead of time which class's or subclass's implementation of the method will be invoked because you don't know what the actual class is.
This idea of having a variable that holds an object of an unknown class is incompatible with C++'s default (non-pointer) mode of storing objects on the stack, where the amount of space allocated directly corresponds to the class. Note: if a class has 5 instance fields versus 3, more space will need to be allocated.
Note that if you are using '&' to pass arguments by reference, indirection (i.e., pointers) is still involved behind the scenes. The '&' is just syntactic sugar that (1) saves you the trouble of using pointer syntax and (2) allows the compiler to be more strict (such as prohibiting null pointers).
Because copying big objects all over the places wastes time and memory.
Here's my anwser, and I won't promse to be an expert, but I've found pointers to be great in one of my libraries I'm trying to write. In this library (It's a graphics API with OpenGL:-)) you can create a triangle with vertex objects passed into them. The draw method takes these triangle objects, and well.. draws them based on the vertex objects i created. Well, its ok.
But, what if i change a vertex coordinate? Move it or something with moveX() in the vertex class? Well, ok, now i have to update the triangle, adding more methods and performance is being wasted because i have to update the triangle every time a vertex moves. Still not a big deal, but it's not that great.
Now, what if i have a mesh with tons of vertices and tons of triangles, and the mesh is rotateing, and moveing, and such. I'll have to update every triangle that uses these vertices, and probably every triangle in the scene because i wouldn't know which ones use which vertices. That's hugely computer intensive, and if I have several meshes ontop of a landscape, oh god! I'm in trouble, because im updateing every triangle almost every frame because these vertices are changing al the time!
With pointers, you don't have to update the triangles.
If I had three *Vertex objects per triangle class, not only am i saving room because a zillion triangles don't have three vertex objects which are large themselves, but also these pointers will always point to the Vertices they are meant to, no matter how often the vertices change. Since the pointers still point to the same vertex, the triangles don't change, and the update process is easier to handle. If I confused you, I wouldn't doubt it, I don't pretend to be an expert, just throwing my two cents into the discussion.
The need for pointers in C language is described here
The basic idea is that many limitations in the language (like using arrays, strings and modifying multiple variables in functions) could be removed by manipulating with the memory location of the data. To overcome these limitations, pointers were introduced in C.
Further, it is also seen that using pointers, you can run your code faster and save memory in cases where you are passing big data types (like a structure with many fields) to a function. Making a copy of such data types before passing would take time and would consume memory. This is another reason why programmers prefer pointers for big data types.
PS: Please refer the link provided for detailed explanation with sample code.
In java and C# all the object references are pointers, the thing with c++ is that you have more control on where you pointer points. Remember With great power comes grand responsibility.
Regarding your second question, generally you don't need to use pointers while programming, however there is one exception to this and that is when you make a public API.
The problem with C++ constructs that people generally use to replace pointers are very dependent on the toolset that you use which is fine when you have all the control you need over the source code, however if you compile a static library with visual studio 2008 for instance and try to use it in a visual studio 2010 you will get a ton of linker errors because the new project is linked with a newer version of STL which is not backwards compatible. Things get even nastier if you compile a DLL and give an import library that people use in a different toolset because in that case your program will crash sooner or later for no apparent reason.
So for the purpose of moving large data sets from one library to another you could consider giving a pointer to an array to the function that is supposed to copy the data if you don't want to force others to use the same tools that you use. The good part about this is that it doesn't even have to be a C-style array, you can use a std::vector and give the pointer by giving the address of the first element &vector[0] for instance, and use the std::vector to manage the array internally.
Another good reason to use pointers in C++ again relates to libraries, consider having a dll that cannot be loaded when your program runs, so if you use an import library then the dependency isn't satisfied and the program crashes. This is the case for instance when you give a public api in a dll alongside your application and you want to access it from other applications. In this case in order to use the API you need to load the dll from its' location (usually it's in a registry key) and then you need to use a function pointer to be able to call functions inside the DLL. Sometimes the people that make the API are nice enough to give you a .h file that contain helper functions to automate this process and give you all the function pointers that you need, but if not you can use LoadLibrary and GetProcAddress on windows and dlopen and dlsym on unix to get them (considering that you know the entire signature of the function).
In some cases, function pointers are required to use functions that are in a shared library (.DLL or .so). This includes performing stuff across languages, where oftentimes a DLL interface is provided.
Making compilers
Making scientific calculators, where you have an array or vector or string map of function pointers?
Trying to modify video memory directly - making your own graphics package
Making an API!
Data structures - node link pointers for special trees you are making
There are Lots of reasons for pointers. Having C name mangling especially is important in DLLs if you want to maintain cross-language compatibility.
I am having my first attempt at using C++11 unique_ptr; I am replacing a polymorphic raw pointer inside a project of mine, which is owned by one class, but passed around quite frequently.
I used to have functions like:
bool func(BaseClass* ptr, int other_arg) {
bool val;
// plain ordinary function that does something...
return val;
}
But I soon realized that I wouldn't be able to switch to:
bool func(std::unique_ptr<BaseClass> ptr, int other_arg);
Because the caller would have to handle the pointer ownership to the function, what I don't want to. So, what is the best solution to my problem?
I though of passing the pointer as reference, like this:
bool func(const std::unique_ptr<BaseClass>& ptr, int other_arg);
But I feel very uncomfortable in doing so, firstly because it seems non instinctive to pass something already typed as _ptr as reference, what would be a reference of a reference. Secondly because the function signature gets even bigger. Thirdly, because in the generated code, it would be necessary two consecutive pointer indirections to reach my variable.
If you want the function to use the pointee, pass a reference to it. There's no reason to tie the function to work only with some kind of smart pointer:
bool func(BaseClass& base, int other_arg);
And at the call site use operator*:
func(*some_unique_ptr, 42);
Alternatively, if the base argument is allowed to be null, keep the signature as is, and use the get() member function:
bool func(BaseClass* base, int other_arg);
func(some_unique_ptr.get(), 42);
The advantage of using std::unique_ptr<T> (aside from not having to remember to call delete or delete[] explicitly) is that it guarantees that a pointer is either nullptr or it points to a valid instance of the (base) object. I will come back to this after I answer your question, but the first message is DO use smart pointers to manage the lifetime of dynamically allocated objects.
Now, your problem is actually how to use this with your old code.
My suggestion is that if you don't want to transfer or share ownership, you should always pass references to the object. Declare your function like this (with or without const qualifiers, as needed):
bool func(BaseClass& ref, int other_arg) { ... }
Then the caller, which has a std::shared_ptr<BaseClass> ptr will either handle the nullptr case or it will ask bool func(...) to compute the result:
if (ptr) {
result = func(*ptr, some_int);
} else {
/* the object was, for some reason, either not created or destroyed */
}
This means that any caller has to promise that the reference is valid and that it will continue to be valid throughout the execution of the function body.
Here is the reason why I strongly believe you should not pass raw pointers or references to smart pointers.
A raw pointer is only a memory address. Can have one of (at least) 4 meanings:
The address of a block of memory where your desired object is located. (the good)
The address 0x0 which you can be certain is not dereferencable and might have the semantics of "nothing" or "no object". (the bad)
The address of a block of memory which is outside of the addressable space of your process (dereferencing it will hopefully cause your program to crash). (the ugly)
The address of a block of memory which can be dereferenced but which doesn't contain what you expect. Maybe the pointer was accidentally modified and now it points to another writable address (of a completely other variable within your process). Writing to this memory location will cause lots of fun to happen, at times, during the execution, because the OS will not complain as long as you are allowed to write there. (Zoinks!)
Correctly using smart pointers alleviates the rather scary cases 3 and 4, which are usually not detectable at compile time and which you generally only experience at runtime when your program crashes or does unexpected things.
Passing smart pointers as arguments has two disadvantages: you cannot change the const-ness of the pointed object without making a copy (which adds overhead for shared_ptr and is not possible for unique_ptr), and you are still left with the second (nullptr) meaning.
I marked the second case as (the bad) from a design perspective. This is a more subtle argument about responsibility.
Imagine what it means when a function receives a nullptr as its parameter. It first has to decide what to do with it: use a "magical" value in place of the missing object? change behavior completely and compute something else (which doesn't require the object)? panic and throw an exception? Moreover, what happens when the function takes 2, or 3 or even more arguments by raw pointer? It has to check each of them and adapt its behavior accordingly. This adds a whole new level on top of input validation for no real reason.
The caller should be the one with enough contextual information to make these decisions, or, in other words, the bad is less frightening the more you know. The function, on the other hand, should just take the caller's promise that the memory it is pointed to is safe to work with as intended. (References are still memory addresses, but conceptually represent a promise of validity.)
I agree with Martinho, but I think it is important to point out the ownership semantics of a pass-by-reference. I think the correct solution is to use a simple pass-by-reference here:
bool func(BaseClass& base, int other_arg);
The commonly accepted meaning of a pass-by-reference in C++ is like as if the caller of the function tells the function "here, you can borrow this object, use it, and modify it (if not const), but only for the duration of the function body." This is, in no way, in conflict with the ownership rules of the unique_ptr because the object is merely being borrowed for a short period of time, there is no actual ownership transfer happening (if you lend your car to someone, do you sign the title over to him?).
So, even though it might seem bad (design-wise, coding practices, etc.) to pull the reference (or even the raw pointer) out of the unique_ptr, it actually is not because it is perfectly in accordance with the ownership rules set by the unique_ptr. And then, of course, there are other nice advantages, like clean syntax, no restriction to only objects owned by a unique_ptr, and so.
Personally, I avoid pulling a reference from a pointer/smart pointer. Because what happens if the pointer is nullptr? If you change the signature to this:
bool func(BaseClass& base, int other_arg);
You might have to protect your code from null pointer dereferences:
if (the_unique_ptr)
func(*the_unique_ptr, 10);
If the class is the sole owner of the pointer, the second of Martinho's alternative seems more reasonable:
func(the_unique_ptr.get(), 10);
Alternatively, you can use std::shared_ptr. However, if there's one single entity responsible for delete, the std::shared_ptr overhead does not pay off.
I'm looking through an API written in C++ and I'm confused as to what the following parameter type means:
void*& data
Does that mean the user would pass in a reference to a void pointer? If that's true, what's the point? I mean void* is already indirected so why would you ever want to redirect it again?
void * means pass-by-pointer in C++, meaning you pass in a pointer, but it's actually a copy of the pointer. If you modified this pointer in your function, like changing its address, it is not reflected in the pointer you passed in.
Combining that with pass by reference, void *& means you are passing an alias of the original pointer to this function. If you modified it, like changing its address, it will be reflected in the original pointer.
It's tough to say without seeing it's use, but you point out that a reference is a level of indirection. Would you find it weird if it was a pointer to a pointer? Those are quite common - in fact you deal with them when accepting command line arguments and get pointers to char pointers. Another example would be if you were making a hash map using buckets, and wanted to be able to return the pointer to the pointer that started the bucket.
The point being is that sometimes you need multiple levels of indirection. It is true that mixing pointers and references can be quirky, but there are good reasons for it. One common reason is the need for C++ code to interact with C apis. A lot of POSIX system calls require void pointers that get passed in and then changed, so the C++ function in question may be acting as a wrapper around that.
But be careful to not return reference to local void*.
Don't do something like this:
void*& f()
{
int* a=new int(10);
void* x=(void*)a;
return x;
}
This question already has answers here:
Closed 12 years ago.
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.]
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.
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).
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).
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.
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.
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.
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.
A pointer has a special value, NULL, that reference's won't. I use pointers wherever NULL is a valid and useful value.
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) {
You can use them for linked lists, trees, etc.
They're very important data structures.
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.