Passing pointers between objects in c++ - c++

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.

Related

Smart pointers with functions returning a pointer in an argument

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.

How can i handle shared_ptr ++

int main ()
{
shared_ptr<int[]> a(new int[2]);
a.get()[0] = 5;
a.get()[1] = 10;
int* foo = a.get();
++foo;
cout << *foo << endl;
return 0;
}
The output is "10" as i expected. But I used regular pointer (int* foo) how can i implement/use ++ operator with only shared_ptr.
A std::shared_ptr contains two parts:
A pointer to the bookkeeping.
A payload-pointer which should be valid at least as long.
So, for your pointer-arithmetic, just use a dependent shared_ptr setting both individually:
shared_ptr<int[]> foo(a, a.get() + 1);
As an aside, an array-shared_ptr supports indexing, so no need to go over .get() for that.
Also, as long as you keep one shared_ptr aroud to keep the data live, there is nothing wrong (actually, it is expected and more efficient) with using raw pointers and references for processing.
There isn't another way.
The only method is to call get and the increment it in the copy returned from the get.
I attach you some usefull link :
smartpointer - shared_ptr
cppreference.com - shared_ptr
What you are trying to do is semantically meaningless. A shared_ptr expresses the intent to own something (in this case an array of two int's). All it does is track ownership. If you increment a shared_ptr, does that mean you release the ownership of the first int? Or does it mean you own the second int twice? Either way is not what you are trying to do.
In general, use unique_ptr/shared_ptr only for ownership issues. To manipulate and use the memory directly, use a view class, something like a span. Not all compilers have this facility yet, so may have to use either the GSL library or write your own. However you implement it, it is better to make a separate object that views the object, but does not claim to own it. If you can tie the length of the array to pointer, this is better still.

How to pass shared_ptr to class with lower lifetime?

I'd like to optimize my code. I have one class that has a shared_ptr data member. In some methods of this class, I create objects that need to use this member (just to get information from the object pointed by shared_ptr). I know that lifetime of these created objects is lower than in my main class.
How to pass this pointer? I think another shared_ptrs is unnecessary (because I have a warranty that the object will exist). So what should get my created classes? Should they get raw pointer? Weak_ptr? Or the best solution is getting shared_ptr (and incrementing its reference counter)? What is the most standard solution?
In this case when you know the life-time of your shared resource will outlive those that you pass the pointer to the correct thing to do is pass a reference or a raw pointer:
void func(object* o)
{
// do stuff with o
}
// ...
std::shared_ptr<object> sp;
// ...
func(sp.get()); // pass raw pointer
The main reason for this is that the function can be useful no matter what kind of smart pointer is managing the resource. By accepting the raw pointer your function is able to accept objects from shared pointers as well as unique pointers and any other third party smart pointer.
There is no benefit to passing in the smart pointer unless the function needs to modify the smart pointer itself.
A good set of guidelines being produced by Bjarne Straustrup & Herb Sutter can be found here: CppCoreGuidelines
The rule about passing raw pointers (or references):
F.7
Passing a smart pointer transfers or shares ownership and should only be used when ownership semantics are intended. A function that does not manipulate lifetime should take raw pointers or references instead.
Passing by smart pointer restricts the use of a function to callers that use smart pointers. A function that needs a widget should be able to accept any widget object, not just ones whose lifetimes are managed by a particular kind of smart pointer.
When passing the shared_ptr into a function that will not store the resource, pass it by reference:
void foo(const shared_ptr<T>& ptr)
{
// Basically just a pointer dereference
std::cout << ptr->bar() << '\n';
}
int main()
{
std::shared_ptr<T> ptr{std::make_shared<T>()};
foo(ptr);
}
That won't increment the reference count, but that's fine — you're effectively treating it as a raw pointer (because you're just temporarily inspecting the pointee) but in a way that's safe because if you accidentally copy it then you'll get the reference count increment that can save your life. :)
However, if foo needs to store any sort of handle to this object, then you should pass in the shared_ptr by copy … or consider using weak_ptr so that you at least get some semblance of safety.
The above contrived example is so simple that I'd actually make it the following:
void foo(const T& ptr)
{
std::cout << ptr.bar() << '\n';
}
int main()
{
std::shared_ptr<T> ptr{std::make_shared<T>()};
foo(*ptr.get());
}

Is it wrong to dereference a pointer to get a reference?

I'd much prefer to use references everywhere but the moment you use an STL container you have to use pointers unless you really want to pass complex types by value. And I feel dirty converting back to a reference, it just seems wrong.
Is it?
To clarify...
MyType *pObj = ...
MyType &obj = *pObj;
Isn't this 'dirty', since you can (even if only in theory since you'd check it first) dereference a NULL pointer?
EDIT: Oh, and you don't know if the objects were dynamically created or not.
Ensure that the pointer is not NULL before you try to convert the pointer to a reference, and that the object will remain in scope as long as your reference does (or remain allocated, in reference to the heap), and you'll be okay, and morally clean :)
Initialising a reference with a dereferenced pointer is absolutely fine, nothing wrong with it whatsoever. If p is a pointer, and if dereferencing it is valid (so it's not null, for instance), then *p is the object it points to. You can bind a reference to that object just like you bind a reference to any object. Obviously, you must make sure the reference doesn't outlive the object (like any reference).
So for example, suppose that I am passed a pointer to an array of objects. It could just as well be an iterator pair, or a vector of objects, or a map of objects, but I'll use an array for simplicity. Each object has a function, order, returning an integer. I am to call the bar function once on each object, in order of increasing order value:
void bar(Foo &f) {
// does something
}
bool by_order(Foo *lhs, Foo *rhs) {
return lhs->order() < rhs->order();
}
void call_bar_in_order(Foo *array, int count) {
std::vector<Foo*> vec(count); // vector of pointers
for (int i = 0; i < count; ++i) vec[i] = &(array[i]);
std::sort(vec.begin(), vec.end(), by_order);
for (int i = 0; i < count; ++i) bar(*vec[i]);
}
The reference that my example has initialized is a function parameter rather than a variable directly, but I could just have validly done:
for (int i = 0; i < count; ++i) {
Foo &f = *vec[i];
bar(f);
}
Obviously a vector<Foo> would be incorrect, since then I would be calling bar on a copy of each object in order, not on each object in order. bar takes a non-const reference, so quite aside from performance or anything else, that clearly would be wrong if bar modifies the input.
A vector of smart pointers, or a boost pointer vector, would also be wrong, since I don't own the objects in the array and certainly must not free them. Sorting the original array might also be disallowed, or for that matter impossible if it's a map rather than an array.
No. How else could you implement operator=? You have to dereference this in order to return a reference to yourself.
Note though that I'd still store the items in the STL container by value -- unless your object is huge, overhead of heap allocations is going to mean you're using more storage, and are less efficient, than you would be if you just stored the item by value.
My answer doesn't directly address your initial concern, but it appears you encounter this problem because you have an STL container that stores pointer types.
Boost provides the ptr_container library to address these types of situations. For instance, a ptr_vector internally stores pointers to types, but returns references through its interface. Note that this implies that the container owns the pointer to the instance and will manage its deletion.
Here is a quick example to demonstrate this notion.
#include <string>
#include <boost/ptr_container/ptr_vector.hpp>
void foo()
{
boost::ptr_vector<std::string> strings;
strings.push_back(new std::string("hello world!"));
strings.push_back(new std::string());
const std::string& helloWorld(strings[0]);
std::string& empty(strings[1]);
}
I'd much prefer to use references everywhere but the moment you use an STL container you have to use pointers unless you really want to pass complex types by value.
Just to be clear: STL containers were designed to support certain semantics ("value semantics"), such as "items in the container can be copied around." Since references aren't rebindable, they don't support value semantics (i.e., try creating a std::vector<int&> or std::list<double&>). You are correct that you cannot put references in STL containers.
Generally, if you're using references instead of plain objects you're either using base classes and want to avoid slicing, or you're trying to avoid copying. And, yes, this means that if you want to store the items in an STL container, then you're going to need to use pointers to avoid slicing and/or copying.
And, yes, the following is legit (although in this case, not very useful):
#include <iostream>
#include <vector>
// note signature, inside this function, i is an int&
// normally I would pass a const reference, but you can't add
// a "const* int" to a "std::vector<int*>"
void add_to_vector(std::vector<int*>& v, int& i)
{
v.push_back(&i);
}
int main()
{
int x = 5;
std::vector<int*> pointers_to_ints;
// x is passed by reference
// NOTE: this line could have simply been "pointers_to_ints.push_back(&x)"
// I simply wanted to demonstrate (in the body of add_to_vector) that
// taking the address of a reference returns the address of the object the
// reference refers to.
add_to_vector(pointers_to_ints, x);
// get the pointer to x out of the container
int* pointer_to_x = pointers_to_ints[0];
// dereference the pointer and initialize a reference with it
int& ref_to_x = *pointer_to_x;
// use the reference to change the original value (in this case, to change x)
ref_to_x = 42;
// show that x changed
std::cout << x << '\n';
}
Oh, and you don't know if the objects were dynamically created or not.
That's not important. In the above sample, x is on the stack and we store a pointer to x in the pointers_to_vectors. Sure, pointers_to_vectors uses a dynamically-allocated array internally (and delete[]s that array when the vector goes out of scope), but that array holds the pointers, not the pointed-to things. When pointers_to_ints falls out of scope, the internal int*[] is delete[]-ed, but the int*s are not deleted.
This, in fact, makes using pointers with STL containers hard, because the STL containers won't manage the lifetime of the pointed-to objects. You may want to look at Boost's pointer containers library. Otherwise, you'll either (1) want to use STL containers of smart pointers (like boost:shared_ptr which is legal for STL containers) or (2) manage the lifetime of the pointed-to objects some other way. You may already be doing (2).
If you want the container to actually contain objects that are dynamically allocated, you shouldn't be using raw pointers. Use unique_ptr or whatever similar type is appropriate.
There's nothing wrong with it, but please be aware that on machine-code level a reference is usually the same as a pointer. So, usually the pointer isn't really dereferenced (no memory access) when assigned to a reference.
So in real life the reference can be 0 and the crash occurs when using the reference - what can happen much later than its assignemt.
Of course what happens exactly heavily depends on compiler version and hardware platform as well as compiler options and the exact usage of the reference.
Officially the behaviour of dereferencing a 0-Pointer is undefined and thus anything can happen. This anything includes that it may crash immediately, but also that it may crash much later or never.
So always make sure that you never assign a 0-Pointer to a reference - bugs likes this are very hard to find.
Edit: Made the "usually" italic and added paragraph about official "undefined" behaviour.

What scenarios would ** be useful? [duplicate]

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.