0

Hi I am trying to understand algorithms But i just don't understand using them in functions. In this case passing a vector into a function. The main issue in understanding is with the return part of the " string* ptrToElement(vector<string>* const pVec, int i)". I dont know why in this function when returning, "return (&( (*pVec)[i] ))", why is does pvec have a *. Why is it a pointer. This is what baffles my understanding, I sont get why pvec has

string* ptrToElement(vector<string>* const pVec, int i);
int main()
{

vector<string> vecInventory;

vecInventory.push_back("sword");
vecInventory.push_back("shield");
vecInventory.push_back("armour");

cout << "Sending the object pointed to by returned pointer: " << endl;
cout << *( ptrToElement(&vecInventory,0) ) << endl << endl;


int iTemp = 0;
cin >> iTemp;
return (0);
}



string* ptrToElement(vector<string>* const pVec, int i)
    {
    return (&( (*pVec)[i] ));
    }
  • `pVec` didn't have to be a pointer. A much more reasonable function would look like this: `string& refToElement(vector& vec, int i) { return vec[i]; }` Though at this point, it's not clear why one needs a helper function at all, rather than just writing `vec[i]` as necessary. – Igor Tandetnik Jul 05 '18 at 03:43
  • well this is actually part of an excercise sheet that was given. I am trying to understand every thing thats in it is in it. The only point that stumps me is with the pvec being a pointer in the return of the function. I am aware of other ways to carry out the primary purpose of this little excercise. But yea... – Enoch Thomas Jul 05 '18 at 03:51

3 Answers3

2

Fei Xiang have given a good explanation. I would like to add an explaination about the *.

In your code, there are two different meanings of *, I think that might be one of the reasons you don't understand it well.

  • vector<string>*, this mean a pointer to a vector object. * is part of the type.
  • (*pVec). * here is dereference the pointer into its pointee. The purpose of dereference here is to use vector's operator [] to access the vector element. You could use pointer to do that directly, code looks like pVec->operator[](i).
2power10
  • 1,259
  • 1
  • 11
  • 33
2

To understand this you just need to visualize what the variables and pointers actually mean in terms of memory locations.

The compiler and program loader will pick real memory addresses and those locations will probably change every time the program is run so we will just make up some values for demonstration purposes.

vecInventory is a vector object and it takes up some memory because it has some data inside it so let's just say for demonstration purposes that it is stored in memory starting at address 100. If you write vecInventory in the program it refers to the vector object.

&vecInventory is the address of the vector object. So &vecInventory is just the number 100 because that is the memory location of the vector object.

So now when you pass &vecInventory to ptrToElement, that function receives the value 100 which it stores in pVec. So pVec contains the number 100.

*pVec means the thing stored at the location stored in the pointer. pVec contains the value 100 which is the memory location of the vector object so *pVec is the vector object.

You could have just passed the vecInventory vector object to ptrToElement directly instead of passing the memory location of the vector object but passing values to a function means copying the value passed. So if you pass a number (like a memory location) only a single number is copied whereas passing an object directly could be a problem if that object is really big because copying something really big could take a while. In this case it doesn't matter because a vector is small (the data you put into a vector is not stored in the vector object).

(*pVec)[i] is the value stored at entry i of the vector. Remember I said the data you put into a vector isn't stored in the vector object? So when i=0 in your example let's just say for demonstration purposes that the value at index 0 of the vector is stored in memory starting at address 50.

&(*pVec)[i] when i=0 is the number 50 because that is the location where the value at index 0 is stored in memory. That means the value returned from ptrToElement(&vecInventory,0) is the number 50.

*( ptrToElement(&vecInventory,0) ) means the thing stored at the location stored in the pointer. ptrToElement(&vecInventory,0) returns the value 50 which is the memory location of the value stored at index 0 so *( ptrToElement(&vecInventory,0) ) is the value stored at index 0 of the vector object.

So in our example demonstration:

  • vecInventory is the vector object (which is stored at memory location 100)
  • &vecInventory is the memory location 100
  • pVec is the memory location 100
  • *pVec is the vector object (which is stored at memory location 100)
  • (*pVec)[i] when i=0 is the value at index 0 of the vector (which is stored at memory location 50)
  • &(*pVec)[i] is the memory location 50
  • ptrToElement(&vecInventory,0) is the memory location 50
  • *( ptrToElement(&vecInventory,0) ) is is the value at index 0 of the vector (which is stored at memory location 50)
Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
  • so correct me if im wrong jerry. I understand that the return type is a rare combination of & and a * for whatever object thats returned. The only other type that i can think of that is similiar to the vector is an array, So if it were an array that was passed in with obviously the function ammended to pass an array in as the argument, will the return be similiar to the vector. ie; say char arr[10]="whatever"; How will returning this array look like now?? – Enoch Thomas Jul 05 '18 at 04:55
  • @EnochThomas No a vector is a object. It's completely different from an array. You do NOT need to pass a pointer to an array because an array automatically decays into a pointer to the data so if you had `string array[3];` you would call `ptrToElement(array,0)` without the `&`. The function would still receive a pointer. – Jerry Jeremiah Jul 05 '18 at 05:03
  • @EnochThomas Ok, so my last comment would have been confusing because I failed to mention WHAT pointer would be passed to the function. The function would receive a `string*` pointer and then you don't need `(*x)[i]` because it isn't a pointer to an array - it is an array so you only need `x[i]` the same as if you had passed the vector by value. – Jerry Jeremiah Jul 05 '18 at 05:16
  • so is this combo of & and * exclusive to vectors?? because this is the first time ive seen a reference to pvec while having a pointer to the vector at the same time. – Enoch Thomas Jul 05 '18 at 05:21
  • @EnochThomas you can take the address of almost anything and then dereference it to get back to the original object. as many have stated above this example is really weak in C++. It's common on C to [avoid copying a large object](https://stackoverflow.com/questions/373419/whats-the-difference-between-passing-by-reference-vs-passing-by-value), but in C++ you will usually see `string& ptrToElement(const vector& pVec, int i)` where `&` makes `pVec` and the returned `string` [referencences](https://en.cppreference.com/w/cpp/language/reference). – user4581301 Jul 05 '18 at 05:38
  • @EnochThomas It applies to everything except an array (because that already decays to a pointer when passed). If you don't want to copy the variable when you pass it in then you have to pass in a pointer instead. For objects that store stuff internally instead of on the heap (which vector does) passing back a pointer to the internals of a copy is undefined behaviour because the copy dies when the function ends and the returned pointer points to nowhere. – Jerry Jeremiah Jul 05 '18 at 05:45
  • thanks man, so i saw your examples and once again I feel like the { return (&( (*pVec)[i] )); } line of code given its function only applies to algorithms like vectors, maps and etc. you would not need to have a return that has a reference and a pointer to that object for other types ie; normal objects or arrays for the reasons given earlier. – Enoch Thomas Jul 05 '18 at 06:18
  • for example for this function header in your link string* ptrToStringHolderRefElement(StringHolder& strHolder, int i) { return (&( strHolder.str )); } Itotally get cuz its just return (&( strHolder.str )); as opposed to return (&( *strHolder.str ));. which makes sense. so i guess the question that im asking you is, is this rare combo of referencing a pointer only for data structures?? ie; vectors, maps, multimaps etc?? – Enoch Thomas Jul 05 '18 at 06:32
  • If you are going to return a pointer to something stored inside an object passed into the function you must pass it by reference/pointer - this doesn't apply to vectors, maps etc because the data isn't stored in the object - it does apply to your own classes/structs. If you are going to modify the item passed in instead of returning it you need to pass it by reference/pointer- this doesn't apply to vectors, maps etc because the data isn't stored in the object - this does apply to primitive types and your own classes/structs. – Jerry Jeremiah Jul 05 '18 at 21:44
  • If the object is huge it's more performant to avoid the copy and pass by reference or pointer - this usually doesn't happen because normally the data isn't stored in the object itself (vectors, maps, etc). Otherwise you can pass by value but there is lots of advice out there saying to pass by const reference (not by pointer) instead of by value for the default case: https://www.google.com/search?q=c%2B%2B+prefer+pass+by+value&oq=c%2B%2B+prefer+pass+by+value&safe=active&ssui=on – Jerry Jeremiah Jul 05 '18 at 21:47
  • but for classes and structs in your example from the link. string* ptrToStringHolderPtrElement(string* pStrHolder) { return (&((*pStrHolder))); } this can easily be substituted for string* ptrToStringHolderPtrElement(string* pStrHolder) { return (pStrHolder); } – Enoch Thomas Jul 06 '18 at 02:49
1

As Igor Tandetnik noted, the code doesn't make a lot of sense.

pVec is a pointer to a vector of strings, and *pVec gives the vector it points to. Then, the [i] gives the string indexed i inside a vector, and finally, the & gives a pointer to the string. So this function returns a pointer to the element indexed i inside a vector of strings pointed to by pVec.

eesiraed
  • 4,626
  • 4
  • 16
  • 34