This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
Uses for multiple levels of pointer dereferences?
I saw a question about ** (pointer to a pointer) in C here. I'd like to know whats the point of this? When should I use it?
Whenever You need a pointer to a pointer :).
For example, if You want to dynamically allocate an array of pointers, operator new or malloc will return a pointer pointing to the first pointer in the array.
Other use might be, to pass a pointer to pointer, to a function, so the function can modify the original pointer. In C++, You can pass by reference, but not in C.
When you have a function which wants to increment a pointer to a c-string. This is needed for things like recursive-descent parsers where each rule is responsible for incrementing things...
In some variation of this:
void PutNewObjectHere(Class **dp) {
*dp = new Class;
}
Class *p;
PutNewObjectHere(&p);
delete p;
(Note, this is a silly example for illustration. It would normally return the new pointer. The concept, however, does occasionally come up in practice)
It's commonly used for out parameters that are pointers, e.g.:
bool GetSomeObject(SomeObject** object) {
*object = new SomeObject();
// ... initialize object or whatever ...
}
And you would call it like thus:
SomeObject* object;
if (GetSomeObject(&object)) {
// ... use object ...
delete object;
}
This is a common pattern where the callee allocates and the caller frees...
You want a C function to mutate a pointer passed as argument, and it's C so there's no pass-by-reference. Therefore you pass a pointer to the pointer. Here's a favorite example adapted from Dave Hanson's C Interfaces and Implementations:
void Bit_free(struct Bit_T **set) {
assert(set && *set);
free(*set);
*set = NULL;
}
By writing NULL into the freed pointer, you prevent it from dangling.
This is called double indirection, meaning you have a pointer to another pointer, which in turn points to some useful data (or in rare cases yet another pointer).
There's a good article at Wikipedia that covers pointers in general and has a good section on double indirection.
In particular I've used these kind of pointers in the context of an array. For instance in my 8086 emulator project I had an array of function pointers. So it ended up looking like this:
instruction_functions[(int)opcode]();
This is also known as a jump table(sorta) and is used in a lot of places for optimization purposes.
Related
This question was discussed a few times but all those discussions almost a decade old and there was no good solution. The question is the same.
We have smart pointers, like unique_ptr, that is great. We have tons of C functions returning a pointer to an object as an argument which later needs to be released.
Let's say this is the function:
int CreateSomething(OBJECT_TYPE** pObject);
So, what would we normally do without smart pointers? Apparently something like that:
OBJECT_TYPE* pObject;
if(CreateSomething(&pObject) == 0) {
// Use the pObject pointer
delete pObject;
}
Now, I would like to rewrite it using smart pointers, and I would like it to be as simple as this:
unique_ptr<OBJECT_TYPE> pObject;
if(CreateSomething(&pObject) == 0) {
// Use the pObject pointer
}
Technically, that would be quite possible if unique_ptr would have T** operator&, and if it would count on this kind of workflow, but it doesn't.
In the case when we want to use a smart pointer here, we have to declare a regular pointer, use it in that function, and then reassign it to the smart pointer. But those extra steps can and should be eliminated, and I hope that maybe there is already an implementation which would allow me to do what I need in that simple manner as I showed.
Yes, I can write my own smart pointer or mediator, which would simplify the usage of unique_ptr, but first I'd like to ask if maybe there is already something implemented in the depth of standard libraries for this and I simply overlooked it?
C++23 has very recently added std::out_ptr for exactly this use case.
write a wrapper: (uncompiled code)
namespace smart_ptrs {
std::unique_ptr<OBJECT_TYPE> CreateSomething() {
OBJECT_TYPE *p = nullptr;
if (::CreateSomething(&p))
return std::unique_ptr<OBJECT_TYPE>(p);
return std::unique_ptr<OBJECT_TYPE>();
}
Then you can write:
std::unique_ptr<OBJECT_TYPE> ptr = smart_ptrs::CreateSomething();
if (ptr) {
// Use the pObject pointer
}
In the case when we want to use a smart pointer here, we have to declare a regular pointer, use it in that function, and then reassign it to the smart pointer.
Basically, yes. That is exactly what you must do (for now anyway, until std::out_ptr is added in C++23).
C++ smart pointers simply do not expose access to their held pointer, thus no way for you to obtain its address to pass to the C function. So, you have to use the smart pointer's constructor or assignment operator instead, which requires the object pointer to already be initialized first.
I'd like to ask if maybe there is already something implemented in the depth of standard libraries for this and I simply overlooked it?
You have not overlooked anything.
I want to ask about passing pointers between functions or between objects or returning them .. I heard that passing or returning pointers in general (whether they point to an array or an object or whatever they are pointing at) isn't safe and the output isn't guaranteed.
now I've tried it and so far everything seems OK but I don't want my project to work by accident .. so can someone explain to me why not to pass or return pointers and what are the suggested solution (for example, what if I want to modify the same object (say object1) in a function in another object (function func in object2))?
also, I read in a tutorial that everything in c++ is pass by value? isn't passing pointers is called pass by reference?
Thanx everybody.
I want to ask about passing pointers between functions or between objects or returning them .. I heard that passing or returning pointers in general (whether they point to an array or an object or whatever they are pointing at) isn't safe and the output isn't guaranteed.
Where did you get that from? In general, it's not true and of course you can pass around pointers.
The tricky thing is managing ownership of (heap-allocated) objects, since somewhere you have to release the memory again. In other words: When you allocate memory with new, you will have to free it again with delete.
Example:
A* function1(A* a) {
return a;
}
B* function2(B* b) {
return new B(b);
}
function1 returns an existing pointer. Whoever owned the A object passed in will also own the returned one, as it is the same. This needs to be documented since this knowledge is essential for using function1!
function2 creates a new object of class B by coping its input argument. Whoever calls function2 will own the returned object and will be responsible to delete it when it's done. Again, this needs to be documented!
also, I read in a tutorial that everything in c++ is pass by value? isn't passing pointers is called pass by reference?
Technically, passing pointers is pass-by-value since the pointer itself gets copied. But since a pointer is a "reference type", you essentially get pass-by-reference with that.
Note that C++ also knows references (int&), which really is pass-by-reference.
Well, the honest answer is that people sometimes mean different things when they say "pass by reference".
But generally, when people say "pass by reference", they mean this:
void readInt(int &a) {
cin >> a;
}
int a;
readInt(a);
cout << a;
And "pass by pointer" would be this:
void readInt(int *a) {
cin >> *a;
}
int a;
readInt(&a);
cout << a;
Ultimately, you can use pointers for everything that references are used for (they other way around is mostly true).
Some people like references because they can use the . operator, like they normally do. Others prefer pointers because they are explicit.
Note that pointers are older than references (C does not have references), so C libraries will use pointers exclusively.
Most people (I think) use references when they can (like in your hypothetical example). The nice thing is that type safety will stop you if you confuse references and pointers.
I'm just getting used to smart pointers using std::auto_ptr.
Assume that I want to call a function with both auto_ptr and normal Pointers.
auto_ptr<uint32> data_smart(new uint32[123])]);
uint32 data_fix[123];
uint32* data_dumb = new uint32[123];
processData(data_smart);
processData(data_fix);
processData(data_dumb);
What is the best practice for this without overloading? Having the processData function with a uint32* argument? Can I cast the smart pointer to uint32* for this case with .get()? Or what is the way I should do it?
Thanks in advance!
1.
auto_ptr<uint32> data_smart(new uint32[123])]);
Don't do that. auto_ptr works with scalars only (it calls delete rather than delete[]).
2.
auto_ptr owns the object it points to, so unless you want to pass the ownership to that function (in your code you don't), the function should accept a normal pointer. So you should change the call to:
processData(data_smart.get());
in order to explicitly express that data_smart continues to own the object.
EDIT: Noah Roberts' comment on your question is the bigger issue here, but this answers the question asked even if the example code is wrong....
... without overloading ...
If you want to do it without overloading, the only option that's going to work for all of these is to make the method take a dumb pointer parameter.
Can I cast the smart pointer to uint32* for this case?
No. Use std::auto_ptr<t>::get().
First of all, you don't initialize auto_ptr with a pointer to array. It's not supported, and you'll end up with memory leaks. std::auto_ptr handles only single objects.
If you still want to use std::auto_ptr, but for single objects only, you need to remember that std::auto_ptr transfers ownership in copy constructor. That means that your local auto_ptr (data_smart) won't hold any memory after you call processData if you pass data_smart by value.
In the end, you probably want to use boost::scoped_array or boost::shared_array.
Best practice is to not use auto_ptr. It will be deprecated in C++0x and replaced by std::unique_ptr (Reference: C++0x Draft Standard, Appendix D, Paragraph 10). In the meantime, alternatives include std::tr1::shared_ptr and boost::scoped_ptr.
But your example is an array, and those pointer types are not for arrays. You can use boost::shared_array for that.
However the Standard itself does not have array smart pointers. That’s probably because they believe you should be using std::vector instead (or std::array for fixed size arrays when you know the size at compile time). Given that, you could do the following:
std::vector<uint32> dataVector;
data.reserve(123);
// or, if the size is always 123:
std::tr1::array<uint32, 123> dataArray;
Now, you can call your function that accepts a regular plain-old uint32* because both vectors and std::tr1::arrays have methods to give you access to the data as a pointer to a C-style array:
processData(&dataVector[0]);
processData(dataArray.data());
I would strongly recommend adding bounds-checking if you are going to do this. Pass a second argument to processData with the size of the array:
processData(&dataVector[0], dataVector.size());
And if you can abandon C-style pointer/arrays entirely, a better way might be to pass by reference:
void processData(std::vector<uint32>& data) {
// process the data
}
// call it like this:
processData(dataVector);
But this only works for vectors, not std::tr1::arrays or any other container. So, taking it one step further, you could use a template that accepts iterators:
template <class AnIterator>
void processData(AnIterator begin, AnIterator end) {
for (AnIterator it = begin; it != end; ++it) {
// process each item
}
}
// call it like this
processData(dataVector.begin(), dataVector,end());
// or like this
processData(dataArray.begin(), dataArray.end());
// or even like this (assume c_data is a C-style array):
processData(c_data, c_data + number_of_items_in_c_data);
The last one works because pointers to C-style arrays can be used as iterators.
In your situation using a vector is the safest choice:
std::vector<uint32> data(123);
The signature of processData should ideally be:
void processData(const std::vector<uint32> & data);
However, this one is more frequently used:
void processData(uint32 * bytes, int length);
In both cases you can use the vector:
// 1
processData(data);
// 2
processData(data.data(), data.size());
Not withstanding why you should want to use auto and dumb (as you put it) pointers for the same data to the same name function without overloading, auto_ptr cannot be used on arrays because it calls the wrong sort of delete.
Have a look at this: http://learningcppisfun.blogspot.com/2007/05/custom-deleters-with-smart-pointers.html
Also have a look at this SO question regarding smart pointers to arrays: auto_ptr for arrays
It amuses me that the data_smart variable is the dumbest of the three. That is, when that scope ends, the auto_ptr destructor is going to call delete on its pointer and not delete[] which leads to UB (which is worse than the possible memory leak from data_dumb).
So, the point is don't use auto_ptr for arrays, use vector.
Onto the real question. First, if possible use reference arguments instead of pointer arguments. If this isn't possible use bare pointers and auto_ptr::get() gives access to the underlying pointer.
Ignoring the already HAMMERED don't use auto_ptr on array.
What is the best practice for this without overloading?
It appears your method will not take ownership, so the remaining question is will it be changed?
Having the processData function with a uint32* argument?
processData( uint32* ) Thats one option, but maybe not the best.
processData( uint32[123] ) if your not editing (123 is starting to push some copying).
processData( uint32 &[123] ) by ref and apply const as necessary.
Can I cast the smart pointer to uint32* for this case with .get()?
You can get the pointer content of the smart pointer using get(), it's already 'typed' so no need to cast it.
Aside:
Data and manipulation of at such a raw level should be in the one class, you probably don't even need to pass what should be a member variable into a member function.
I have seen stack class that uses the template to define the type of data the stack hold. What if I want a stack that hold different type of data? I have a little thought into it and come close to using void pointer (but void pointer can't be dereferenced, so it is not the correct solution) So... Is it possible to have such a class?
You could have a stack of boost::any values.
There are various options, listed here from the safest to the most difficult to manage
A common base class
boost::variant (assuming you know all types beforehand)
boost::any (very difficult to act on, since anything can be in there...)
void* (very difficult once more and there is a memory management issue)
Pick up the one you wish.
void pointers can't be dereferenced, sure, but you can still cast the void pointer to the actual type of pointer you need, and then dereference it.
void *ptr = malloc(10);
*ptr = 10; // won't work
*((int *)ptr) = 10; // will work
You should have a look at C++ templates. This way you can design classes or functions to work on any data type.
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What are the differences between pointer variable and reference variable in C++?
What does Class& mean in c++ and how is it different from Class*?
Class& foo;
Class* foo;
The & version represents a reference while the * version represents a pointer. The difference is far too big for a typical SO post. I suggest you start at the C++ FAQ lite
http://www.parashift.com/c++-faq-lite/references.html
I usually don't like to answer posts with a "you should use google" answer. However this is one topic that I highly advise you google. In particular google "c++ pointers vs. references". There is a wealth of information available on this topic and the discussions on those pages will trump anything we'll write here.
The * is a pointer, the & is a reference. The difference between the two is that a pointer is an area of memory that must be dereferenced, eg. by means of the -> operator in order to be "seen" as a class instance. A reference is instead an "alias", just an alternative name for the same class instance. You don't need to use the -> operator with a reference. You use the dot operator.
Personally, I rarely used the references, mostly when I had a value object that I allocated on the stack. The new operator always returns a pointer, which you then have to dereference. Moreover, one of the most problematic issues of the references is that you cannot set them to NULL. In some cases, it is handy to have a function that accepts either an object pointer or NULL. If your function accepts a reference, you cannot pass a NULL (you could use the Null object pattern, however)
A Class * can point at any class object, or none.
A Class & always points to exactly one class object, and can never point to a different one.
Furthermore, I believe Bjarne is a member of the set of people who have asserted "arrays in C are broken beyond repair," a Class * can point at a whole ding-dang array of class objects, lined up one after the other in memory, and there is absolutely no way in C to tell whether a Class * points at one or many.
Another difference is that reference variables must be initialized. You cannot create a reference variable like what is shown in the sample code. That would produce a compiler error.
As stated you should google it, but to avoid misunderstanding:
References are NOT variables
References are NOT similar to pointers (but you can use them in a similar way)
Think of a Reference as a shortcut for the term that is assigned to it.
One additional tip that I would offer is the following:
Use references when you can, pointers when you have to. If the object is guaranteed to exist, you should probably use a reference. If it is not, then you probably have to use a pointer.
One additional advantage is that references remove ambiguity on ownership. As soon as a maintenance programmer sees a pointer, they'll start to wonder if they should delete it.
Check this example out:
// Wrapper class using a reference because the wrapped object always exists
class Wrapper
{
public:
// If the wrapped is guaranteed to exist at creation, do it this way
Wrapper(Wrapped& wrapped):_wrapped(wrapped) { /* empty */ }
// put extra methods here.
int getWrappedValue() const { return _wrapped.getValue(); }
private:
Wrapped& _wrapped; // This object always exists and is valid
};
// Wrapper class written to support a possibly non-existent wrapped object.
class Wrapper
{
public:
Wrapper(Wrapped* wrapped = 0):_wrapped(wrapped) { /* empty */
void setWrappee(WRappee* wrapped) { _wrapped = wrapped; }
int getWrappedValue() const; // Not making inline -- more complex
private:
Wrapped* _wrapped; // Always check pointer before use
};
int Wrapper::getWrappedValue() const
{
if (_wrapped)
{
return _wrapped->getValue();
}
else
{
return -1; // NOTE, this is a contrived example -- not getting into exceptions
}
}
A reference (&) is just the same as a pointer (*), except that the C++ compiler ensures it not to be NULL. However, it can still be a dangling pointer (a pointer variable that has no reference such that it is garbage and invalid for any use).