Skip to main content
gamedev.net
🔒 Locked

passing a pointer by reference...why?

Started by GekkoCube 16 replies 1.2k views
Original Post
GekkoCube
GekkoCube
what are the benefits?
cgoat
cgoat
So that you don''t have to use int **, in order to be able to change the pointer.
GekkoCube
GekkoCube
perhaps i havent done enough of this...

but if:


void SetData(Object *obj)
{
obj->data = m_data;
}


wouldnt this object''s data member change once this function is returned?

if so, which i do believe it does, what is the point of passing this object by reference since we''re simply passing a pointer.
Agony
Agony
void CreateObject(Object*& obj)
{
obj = new Object;
obj->data = m_data;
}
This is a common reason. The pointer is passed in, without pointing to anything, or hopefully, since it is clearer, NULL. The purpose of the function is to create a new instance of Object, or at least, that''s one of the things that happens in the function. Since we set the pointer to new Object, the pointer is different now, and we need to let the outside world know that, thus we pass the pointer by reference.
"We should have a great fewer disputes in the world if words were taken for what they are, the signs of our ideas nly, and not for things themselves." - John Locke o
cody
cody
if you pass the pointer by reference the function could return a pointer.
mfawcett
mfawcett
Reallocation comes to mind, although there are a lot of ownership questions that come into play with that scenario.

std::auto_ptr would help with those semantics.

But back to your original post, here''s an example:

int main(void)
{
int *p = new int[10];

resizeInt(p, 20);
}

void resizeInt(int *&arr, size_t sz)
{
delete [] arr;
arr = new int[sz]
}

Without passing by reference (or double pointer, with resizeInt(&p, 20) ), the original pointer ''p'' would never have been changed to point to the newly allocated memory.

Generally, returning a pointer would''ve been a better alternative than a pointer-to-pointer or reference-to-pointer parameter solution. But there''s still the question of who''s responsibility it is to cleanup that memory, unless you use a std::auto_ptr.
--Michael Fawcett
Zipster
Zipster
The benefit is cleaner syntax inside your function body, so you don''t have to defer your pointer all over the place.
mfawcett
mfawcett
On a slightly related note (not meant to hijack the thread), I think that non-const references of any type should be avoided as parameters to functions. It is unclear to the caller whether or not his parameter is being modified. When you explicitly pass in your address as a non-const parameter, you are knowingly walking into a situation where your information could (probably will, or else it should''ve been const) be changed.
--Michael Fawcett
Zipster
Zipster
I''ve always just assumed that if it wasn''t const, it was being modified. As you said, otherwise it would have been const. And while there really isn''t any strict enforcement of this rule, most programmers worth their salt would const a reference type if it isn''t supposed to be modified - for their own sake if anything, since you''d get a compiler error if you did try to do anything.
rypyr
rypyr
quote:
Original post by Anonymous Poster
what''s wrong with making the method return a pointer to the newly-allocated object?



What if you also want the method to return one of a number of error codes if the allocation fails? Yes there are other ways, but a reference-argument makes this possible with the existing interface.

Typically any well-documented system will clearly label its "out" function parameters so that it should be obvious if you''re going to modify the referred to data. Anyway, my code would

I find nothing wrong with references as outgoing function parameters, etc. Ada has it

And like any potentially abused language feature, it''s all a matter of how use it. Just like operator overloading, goto and the preprocessor.

Regards,
Jeff



[ CodeDread ]
azurianarcher
azurianarcher
quote:
Original post by mfawcett
But back to your original post, here''s an example:

int main(void)
{
int *p = new int[10];

resizeInt(p, 20);
}

void resizeInt(int *&arr, size_t sz)
{
delete [] arr;
arr = new int[sz]
}

Without passing by reference (or double pointer, with resizeInt(&p, 20) ), the original pointer ''p'' would never have been changed to point to the newly allocated memory.



I compiled two examples using the above function, one using resizeInt(int *&arr, size_t sz) the other suing resizeInt(int *arr, size_t sz) and they both behaved exactly the same, im not sure what this means though, heres the main function:

int main(int argc, char* argv[])
{
int *p = new int[10];

p[5] = 10;
cout<<"p[5]: "<<p[5]<<endl;

resizeInt(p,20);

p[15] = 20;
cout<<"p[15]: "<<p[15]<<endl;

while(!_kbhit()){}
return 0;
}


~Amx

mfawcett
mfawcett
Sounds like you were lucky not to crash, although you didn''t paste the source code for the resizeInt(int *arr, size_t sz) function.

But if that was your prototype, your program was exhibiting undefined behavior, because at that point, the memory ''p'' was pointing to had been deleted, and even if it hadn''t been, 15 is out of bounds of the dynamic array it was once pointing to.

Try running in Release mode, I''d be interested to hear back. What compiler are you using?
--Michael Fawcett
mfawcett
mfawcett
quote:
Original post by rypyr
quote:
Original post by Anonymous Poster
what''s wrong with making the method return a pointer to the newly-allocated object?


Typically any well-documented system will clearly label its "out" function parameters so that it should be obvious if you''re going to modify the referred to data. Anyway, my code would

I find nothing wrong with references as outgoing function parameters, etc. Ada has it


So does the Maya API, but that doesn''t mean it''s a good programming practice. That requires you look at docs or comments to realize it''s an "out" parameter, whereas the second you give someone the variable address, you know it can and will probably be modified.
--Michael Fawcett
azurianarcher
azurianarcher
Heres the source code:

// pointerreftest.cpp : Defines the entry point for the console application.

//


#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;

int main(int argc, char* argv[])
{
int *p = new int[10];

p[5] = 10;
cout<<"p[5]: "<<p[5]<<endl;

resizeInt(p,20);

p[15] = 20;
cout<<"p[15]: "<<p[15]<<endl;

while(!_kbhit()){}
return 0;
}

Heres one of the resizeInt functions i used:

void resizeInt(int *&arr, size_t sz)
{
delete[] arr;
arr = new int[sz];
}

And heres the other

void resizeInt(int *arr, size_t sz)
{
delete[] arr;
arr = new int[sz];
}


The output is as follows:
quote:

p[5]: 10
p[15]: 20



This is the output in both release and debug, im using msvc++ 6.0

~Amx
mfawcett
mfawcett
Clean up the rest of the memory in by putting a delete [] p; before main ends. That''s a flaw with the current program, and might produce the crash that should be happening.

I''m not at a computer with a compiler so I can''t try it out, but I can definitely tell you that you''re getting lucky and you shouldn''t rely on that behavior.
--Michael Fawcett
azurianarcher
azurianarcher
yup, that did it. When would uever need to use this though

~Amx

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.