• Advertisement
Sign in to follow this  

Pointing to a pointer(?) Minor confusion. . .

This topic is 4256 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

All of the following materials are taken from a book and are not homework assignments (plus it's summer :) ). As I was reading some of the basics of pointers in my C++ book, I recognized a bit of code that confused the hell out of me. . .
// Inventory Pointer
// Demonstrates returning a pointer

#include <iostream>
#include <string>
#include <vector>

using namespace std;

//returns a pointer to a string element
string* ptrToElement(vector<string>* const pVec, int i);

int main()
{
    vector<string> inventory;
    inventory.push_back("sword");
    inventory.push_back("armor");
    inventory.push_back("shield");

    //displays string object that the returned pointer points to
    cout << "Sending the objected pointed to by returned pointer:\n";       
    cout << *(ptrToElement(&inventory, 0)) << "\n\n";
. . . and it continues on. . .


and the ptrToElement function. . .
string* ptrToElement(vector<string>* const pVec, int i)
//returns address of the string in position i of vector that pVec points to
return &((*pVec));  


Now here's where my confusion lies, what I see is a pointer to a function with the address of inventory and the integer "0" as arguments. When we look at the function we see that a pointer to a string should be returned. All the function does is return the reference of what pVec (inventory) is pointing to with the string the number represents. Wait. . .aren't we supposed to be returning a pointer? My theory was that the address of the return value is stored in the pointer that the function returns to int main(). That would make sense, but why the * around the function if it's returning a pointer, is this a pointer to a pointer? Someone end the confusion. :)

Share this post


Link to post
Share on other sites
Advertisement
I have another question unrelated to this. . .

My friend has been working on images and rules for a 2D card game, based off of the popular Warcraft series. The game will be graphical and features, a battle area, and many cards/spells/ whatever else he can think of. Guess who he wants to do ALL the programming :).

Seeing as how I'm obviously still learning, how long until I should be able to get something started. I'm reading this book. . .

http://www.amazon.com/gp/product/1592002056/102-7684400-1047316?v=glance&n=283155

. . . and I'm not sure if I covers everything to the point that I should feel comfortable with moving on to SDL. It covers a lot of great things, but also misses some important bits like streaming. With beginning SDL as my main goal, how long (In your opinion), until I should start?

Share this post


Link to post
Share on other sites
Aside from the fact that the code is horrible [wink], let's see what happens there.

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


Obviously the input to the function is a pointer to a vector of strings.
Let's dissect the return statement of that function:

return &((*pVec));


The expression (*pVec) de-references the pointer-to-vector-of-strings that the function receives, basically providing access to its member functions without using the arrow operator.
The -part invokes the overloaded indexing-operator. Note that the following statements are semantically equal:

// de-reference first, call indexing operator on the de-referenced pointer
(*pVec);
// use the arrow-operator on the pointer to access the indexing operator -
// note the cumbersome syntax :)
pVec->operator[](i);


Now the expression (*pVec) yields a reference to the string stored at index i. In order to return a pointer to this string, the address-of operator is finally applied to the result.
You can also write these steps in a less condensed way for clarity:

// 1) de-reference the input
vector<string> & vecref = *pVec;
// 2) get a reference to the content stored at index "i"
string & strref = vecref;
// 3) return the address of the string
return &strref;



HTH,
Pat.

Share this post


Link to post
Share on other sites
Ok, I understand what you have done, but the question remains, is this function returning a pointer or an address? Why is a "*" needed around the function in int main()?

Share this post


Link to post
Share on other sites
Quote:
Original post by kevtimc
Ok, I understand what you have done, but the question remains, is this function returning a pointer or an address? Why is a "*" needed around the function in int main()?

Well, since the function returns a pointer to a string and std::cout expects a reference in order to actually output the string, you need to de-reference it again.
If you fail to do so, the actual value of the pointer (i.e. the memory address the string is located at) will be displayed by std::cout.

Share this post


Link to post
Share on other sites
Quote:
Original post by kevtimc
Ok, I understand what you have done, but the question remains, is this function returning a pointer or an address?


Both; it is returning a pointer by value. This means returning the value of the pointer, which is a memory address, and which is not the value in the memory at that address.

Share this post


Link to post
Share on other sites
Quote:
Original post by Geoff the Medio
Quote:
Original post by kevtimc
Ok, I understand what you have done, but the question remains, is this function returning a pointer or an address?


Both; "returning a pointer" means returning the value of the pointer, which is a memory address, and which is not the value in the memory at that address.


So why not just say you're returning an address?

Share this post


Link to post
Share on other sites
Quote:
Original post by kevtimc
Quote:
Original post by Geoff the Medio
Quote:
Original post by kevtimc
Ok, I understand what you have done, but the question remains, is this function returning a pointer or an address?


Both; "returning a pointer" means returning the value of the pointer, which is a memory address, and which is not the value in the memory at that address.


So why not just say you're returning an address?

Because the C++ way of saying just that is to return a pointer [smile].

Share this post


Link to post
Share on other sites
Quote:
Original post by kevtimc
So why not just say you're returning an address?


For data-type verification purposes, it's helpful to specify what is being pointed to. So one returns "(the value of) a pointer to Type", not just "an address".

Share this post


Link to post
Share on other sites
Thanks, so what I got out of this is that you tell the complier your returning a ponter so it knows your not just returning an address, but an address that will be pointed to by a pointer. I guess I should keep this thread alive for my other question.

Share this post


Link to post
Share on other sites
Quote:
Original post by Geoff the Medio
Quote:
Original post by kevtimc
So why not just say you're returning an address?


For data-type verification purposes, it's helpful to specify what is being pointed to. So one returns "(the value of) a pointer to Type", not just "an address".

Not just data-verification.
In this specific example, the ostream object that handles console output wouldn't even know what to do with "just an address". "Just an address" would be some integer and de-referencing that would not return anything useful. By converting a pointer to an object to a generic address, all type information will be lost.

This means that the compiler will not be able to figure out what you are refering
to unless it is explicitly told so by using an unsafe type cast.

It's certainly both possible and valid to re-write the code as follows:

// void * is semantically equal to "just an address"
void * ptrToElement(vector<string>* const pVec, int i);

int main() {
// ...
cout << *static_cast<string*>(ptrToElement(&inventory, 0)) << "\n\n";
// ...
}



But it should be obvious that this code offers no advantage over the original code, besides being misleading (it doesn't do what it says it does, i.e. it returns "just some address", while it still really returns a pointer to a string) and dangerous (suppose you cast to the wrong type...).

Cheers,
Pat.

[EDIT]
One more thing has to be considered in this context - a void * isn't necessarily the same size as a pointer to a class or a pointer to a class member function!
So returning "just a (generic) address" could result in truncation and hence lead you to the great land of undefined while de-referencing.
[/EDIT]

Share this post


Link to post
Share on other sites
Quote:
Original post by kevtimc
... you tell the complier your returning a ponter so it knows your not just returning an address, but an address that will be pointed to by a pointer.


Well, sort of... You'd (almost) never just return an address with no associated type information. If you're passing data around, it's just about always going to be data of a particular type, whether ints, or structs or objects, or pointers to objects, etc. So just like you return an int by value sometimes, and not 4 bytes of nonspecific data, later to casted to int so it can be actually used, you also return a pointers to particular types, rather than 4 bytes of nonspecific data, later to be casted to a pointers to some type.

It's also more so for you than for the compiler. For you, if trying to use some function, it's helpful to know what type the returned address points to. This is particularly true for using someone else's code; it would be difficult to use a set of functions that just returned addresses, but didn't specificy what kind of object or data was being pointed to by these addresses.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement