🔒 Locked
passing a pointer by reference...why?
Advertisement
Original Post
perhaps i havent done enough of this...
but if:
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.
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.
void CreateObject(Object*& obj)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.
{
obj = new Object;
obj->data = m_data;
}
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:
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.
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.
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.
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.
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 ]
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
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?
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?
quote:
Original post by rypyrquote:
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.
Heres the source code:
Heres one of the resizeInt functions i used:
And heres the other
The output is as follows:
This is the output in both release and debug, im using msvc++ 6.0
~Amx
// 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
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.
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.
yup, that did it. When would uever need to use this though
~Amx
~Amx
Topic Locked
This topic has been locked by a moderator. New replies are not allowed.
Sign in to reply to this topic.
Advertisement