|
|
Comments and Discussions
|
|
 |

|
Hi, this is great article, really helpful to understand PTP and RTP! Thank you for posting this!
Still I have a question, about returning pointer method.
Using this method, how do you implement func() and main() which perform same as the functions when you used to explain pointer to pointer or reference to pointer?
I couldn't understand the part you used "return new int", and why it can be alternative for PTP and RTP methods.
Thank you so much for your help in advance!
from Nao
|
|
|
|

|
Assuming your class is MyClass, you can allocate the memory in func using new and return the ptr but remember to delete it.
MyClass* func()
{
MyClass* ptr = new MyClass();
return ptr;
}
|
|
|
|

|
Wow, thanks, it makes sense to me. Thanks again, you are awesome!
|
|
|
|

|
As you said: "If you find that the ptr-to-ptr and ref-to-ptr syntax are rather hard to understand, you can just use the "return the pointer" method." In return the pointer method, can we return 2 pointers after modifying them in the function?
|
|
|
|

|
You can use a structure to hold 2 pointers and return that structure instead.
|
|
|
|

|
Thanks!
|
|
|
|

|
Thank you, very good explanation
|
|
|
|

|
Very good explanation. I was havin confusions before reading this article.
|
|
|
|
|

|
I was confused about the pointer and reference syntax and was wondering if there is a way to pass the reference of a pointer. The article was exactly what I was looking for. Thx for writing
|
|
|
|

|
I'm porting a VC++ project from VC98 to VS2008 and here's what I'm up against in a particular code segment.
We've got a class called DVARElement.
We've got a function that is prototyped to take a const DVARElement *&
This code segment is throughing an error:
DVARElement buf;
DVARElement * ptrBuf = &buf;
pForm->Execute(ptrBuf);
Throws.
Error 1 error C2664: 'HRESULT ndcForm::Execute(const PtrType *& pItem) const' : cannot convert parameter 1 from 'DVARElement *' to 'const DVARElement *&'
I'm guessing I have to do something with the const, but I've tried several things to no avail.
|
|
|
|

|
I think in your example you have maid a crucial mistacke and wrong conclusions!!!
// A successful attempt to modify caller arguments
#include <iostream>
using std::cout;
using std::endl;
//global variable
int g_One=1;
//function prototype
void func(int* pInt);
int main()
{
int nvar=2;
int* pvar=&nvar;
func(pvar);
std::cout<<*pvar<<std::endl;//Will show 1
return 0;
}
void func(int* pInt)
{
*pInt=g_One;
}
|
|
|
|

|
Hi zired,
In your example, after the func call, pvar is still pointing to nvar and now nvar holds 1, instead of the original value, 2. pvar is supposed to change to point to g_One, after the func call.
Please kindly approach me if you are unclear or still have any other questions.
Thanks for asking.
|
|
|
|

|
I think in your example you have maid a crucial mistacke and wrong conclusions!!!
// A successful attempt to modify caller arguments
#include <iostream>
using std::cout;
using std::endl;
//global variable
int g_One=1;
//function prototype
void func(int* pInt);
int main()
{
int nvar=2;
int* pvar=&nvar;
func(pvar);
std::cout<<*pvar<<std::endl;//Will still show 2
return 0;
}
void func(int* pInt)
{
*pInt=g_One;
}
|
|
|
|

|
I'm recently learning C#. In C# you can pass parameters by value or by reference, and as you know, there are value types and reference types in C#.
I don't know if reference in C# means the same thing as in C++. But I think passing a reference type by reference in C# is similar to passing a pointer "by reference" in C++ (Reference to Pointer). As in both cases, the callee can change the values of the object’s state data as well as the object the ref type/pointer is referencing/pointing to.
What do you think?
I've written a program in C++ using "Reference to Pointer".
#include <iostream>
#include <string>
using namespace std;
class Person
{
private:
string name;
public:
Person(string s)
{
name = s;
}
Person()
{
name = "";
}
void SayHello()
{
cout << "Hello, my name is " << name << "!" << endl;
}
};
void Swap(Person *& a, Person *& b)
{
Person *temp;
temp = a;
a = b;
b = temp;
}
int main()
{
Person *p1 = new Person("Alice");
Person *p2 = new Person("Bob");
cout << "Before swapping:" << endl;
p1->SayHello();
p2->SayHello();
cout << endl << "Memory address of *p1:" << p1 << endl;
cout << "Memory address of *p2:" << p2 << endl;
Swap(p1, p2);
cout << endl << "After swapping:" << endl;
p1->SayHello();
p2->SayHello();
cout << endl << "Memory address of *p1:" << p1 << endl;
cout << "Memory address of *p2:" << p2 << endl;
delete p1;
delete p2;
return 0;
}
This program swaps the objects that p1 and p2 points to by passing them to Swap() by reference.
However, if I define Swap() like this:
void Swap((Person *) &a, (Person *) &b)
the compiler would display some error messages.
Swap.cpp(27) : error C2065: 'a' : undeclared identifier
Swap.cpp(27) : error C2065: 'b' : undeclared identifier
Swap.cpp(28) : error C2448: 'Swap' : function-style initializer appears to be a function definition
Swap.cpp(47) : error C3861: 'Swap': identifier not found
I really don't know why there would be errors. Why are those two definitions different?
Finally, I wonder if you know how to do the same swapping job in Java. As you know, in Java I can only pass parameters by value. Do you have any solutions?
|
|
|
|

|
Hi lhyblue,
I am terribly sorry for the late reply as I was rushing for my open source library and its article: Outline Text[^]
You are right in saying that "passing a reference type by reference in C# is similar to passing a pointer "by reference" in C++ (Reference to Pointer). As in both cases, the callee can change the values of the object’s state data as well as the object the ref type/pointer is referencing/pointing to."
As for the Swap definition, you cannot define the parameters in parenthesis in C/C++.
As for the Java question, I do not know much about Java to comment on it. In other words, I do not have a swap solution for Java, as you have said Java pass parameters by value. Let's hope the upcoming Java 7 has some features which address this 'deficiency'.
|
|
|
|

|
a long artikel for a simple basic info, a c-programmer must know this basics
|
|
|
|

|
Hi Country Man,
You might be interested to know that I got a C/C++ programming job, 5 years ago because of this ptr-to-ptr article. The manager told me that many C/C++ programmers after 10 years of C/C++ programming, still do not know pointers are passed by value, which means a copy of it is passed. The manager was impressed by my C knowledge. Perhaps, you would like to read the article in detail if you haven't done so. Thanks for commenting.
|
|
|
|

|
You give example:
//global variable
int g_One=1;
//function prototype
void func(int* pInt);
int main()
{
int nvar=2;
int* pvar=&nvar;
func(pvar);
std::cout<<*pvar<<std::endl;//Will still show 2
return 0;
}
void func(int* pInt)
{
pInt=&g_One;
}
why not using memcpy then?
void func(int* pInt)
{
//pInt=&g_One;
memcpy(pInt, &g_One, sizeof(int));
}
i think it is the same like strdup vs strcpy.
i mean if you are passing char* instead of int*, use strcpy since it copies data to its given pointer.
correct me...
i'm a newbie...
From Indonesia with love..!!
|
|
|
|

|
Hi auralius,
Memcpy does not work because pInt is a copy of the pointer. What you are copying into, is a copy of the pointer, the original pointer is still unchanged. This is the reason why we need pointer to pointer or reference to pointer.
Hope this clears the confusion.
|
|
|
|

|
void func(int* pInt)
{
//pInt=&g_One;
memcpy(pInt, &g_One, sizeof(int));
}
i did try...
it works...
memcpy : copies the values of num bytes from the location pointed by source directly to the memory block pointed by destination.
(cplusplus.com)
From Indonesia with love..!!
|
|
|
|

|
Hi Auralius,
Your code example modifies nvar to 1 and pvar is still pointing to nvar. I only want to modify the pvar to point to g_One without modifying nvar and that is only possible with ptr-to-ptr or ref-to-ptr.
std::cout<<(void*)pvar<<std::endl; std::cout<<(void*)&nvar<<std::endl;
Hope this clears the air!
Thank you!
|
|
|
|

|
A very usefull capability would be pointer type casts and references.
For example, Take a common routine such as a chain. The nodes are defined as:
Class Node {
private:
Node *next, *previous;
void *value;
public:
Node() { next = previous = 0; value = 0; };
~Node();
void *Get(); // returns 'value'
void *Get(int index) // returns 'value' for 'index' node
void Set(void *newvalue); // set 'newvalue'
void Set(int index, void *newvalue); // set 'newvalue' in 'index' node
void Preinsert(void *newvalue); // insert new node before this
void Postinsert(void *newvalue); // insert new node after this
void unlink(); // unlink this node
};
#define chain(newclass) class newclass##chain : public Node \
{ \
public: \
newclass *get() { return (newclass *)Get(); }; \
newclass *get(int ii) { return (newclass *)Get(ii); }; \
void set(newclass *p) { Set((void *)p); }; \
void preinsert(newclass *p) { Preinsert((void *)p); }; \
void postinsert(newclass *p) { Postinsert((void *)p); }; \
newclass *operator[](int ii) { return (newclass *)Get(ii); }; \
};
And now you can create a chain class for say class 'Tree' called 'Treechain' by specifying:
chain(Tree);
Works great for right side:
Treechain tc1;
Tree *tp;
...
tc1.postinsert(&Tree(...));
tc1.preinsert(&Tree(...));
...
tp = tc1[ii];
...
But not for the left side. How do you get it to take:
tc1[jj] = tp;
??
You need it to convert from (void *) to (Tree *) and passed to the referenced value.
|
|
|
|

|
this is what I'm looking for, very nice article,
FYI google codesearch is online, still beta but useful.
I found this when I search for ****ptr
Google code search lang:"C++" \*\*\*\*\*ptr
Please google for code search
insert
lang:"C++" \*\*\*\*\*ptr
and we find
template
inline void ALLOC4D(Etype *****ptr, int m, int n, int o, int p)
this shows that it is needed but sometimes tricky to debug.
On the other hand &&&&ptr would make no sense.
Please correct me If I'm wrong.
// Lord Byte has started to code
void swap(char **p, char **q)
{
char *tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
|
|
|
|

|
Hi morten41,
I couldn't find the code, ALLOC4D() which you specified. I think from the function name, I could roughly tell that it is allocating a 4 dimensional array and parameters m, n, o and p are the dimensional sizes. Hope it helps!
Best regards,
Wong Shao Voon
|
|
|
|

|
Yes it was tricky to find,
sun has a java code search engine, which I find very useful.
Here it is, at least on my Windows XP.
http://666kb.com/i/at3bnqwh78hmyd4i8.jpg[^]
http://www.anirudh.net/phd/posse/html/html/alloc_8h-source.html[^]
Sure I will come back to your article,
Currently I find some strange problems
during debugging some pointer to pointer C code.
A good explanation about redirection, referencing and usage of pointers should be
proven correct for any arbitrary level of pointer to pointer referencing.
Especially memory leaks or crashes but also knowledge what is going in the stack,
on the heap, and what exactly is the case if the Memory is forced to create a
virtual swap file.
Please tell me your opinion about the google code search.
In my eyes the best C Code I have ever used is the one I have verified and tested
from Numerical recipes in C.
Should work now, I simply had to use rational rose Purify plus to at least improve some of my code. But the Visual studio debugger is great also.
// Lord Byte has started to code
void swap(char **p, char **q)
{
char *tmp;
tmp = *p;
*p = *q;
*q = tmp;
}
|
|
|
|

|
Hello,
Your report helps me to understand more about all this pointer and reference stuff.
I tried to get such an example to work in .Net 2005. But there are always some compiler errors such as:
cannot convert parameter 1 from 'imgKernel::Image *' to 'imgKernel::Image *&'
Do you know, how to pass my reference to pointer to a function in .NET.
Thanks for your help.
|
|
|
|

|
Hi, you are using what language? C#, C++/CLI or C++?
|
|
|
|

|
Hello,
Sorry.. I'm using managed C++ (CLI).
|
|
|
|

|
// C++/CLI Example
// function prototype
void foo( String^% str );
// function definition
void foo( String^% str )
{
str = gcnew String("Hello");
// or
str = "Hello";
}
String^ str=nullptr;
// Function call
foo(str);
/////////
/////////
/////////
// C++ Example
// function prototype
void foo( std::string*& pStr );
// function definition
void foo( std::string*& pStr )
{
pStr = new std::string("Hello");
}
std::string* pStr=NULL;
// Function call
foo( pStr );
How to: Pass CLR Types by Reference with Tracking References[^]
Edited: added a MSDN link
|
|
|
|

|
What is the difference between the 2 following functions?
Function my_function_1 ($input_1) {
$input_1 + = 100
return $input_1;
}
//and
Function my_function_2 (&$input_2) {
$input_2 + = 100;
return $input_2;
}
can i have an advantage and disadvantage for each method please
hamid
|
|
|
|

|
Do you mean * instead of $ ? I don't see any difference, in terms of what they do.
If you didn't mean *, then $ is not a valid name for a variable.
Christian Graus - Microsoft MVP - C++
|
|
|
|
|
|

|
Here's all the ways you've got it wrong
1. Asking a general question ( assuming it's a question ) in a specific article forum
2. Posting anonymously
3. Not describing your problem in detail
4. Having the gall to say 'please reply fast' when asking one specific person to help you for free
5. Thinking that a compiled C++ program has any ability to know what it's source code was. It can't. The source code is gone. If you want to print it, you need to include it as a resource, and you have no guarentee that the source you include is the same as the source that was compiled.
Christian Graus - Microsoft MVP - C++
|
|
|
|

|
Thank you much for this article. I have programmed C++ for oh I don't now 10 years now. Every once in awhile something tottally baffles me....today I needed to pass a pointer to a function and have that value modified...you would think after 10 years experience I would knwo such things, but it just goes to show you that as a programmer you will always be learning...
BTW I searched google for about 45 minutes tyring to figure this out...I was even digging through some gcc bug tracks thinking it might have been a compiler error.
Thanks
|
|
|
|

|
You only use either of them when you need to modify a pointer, passed to the function, inside that function. Otherwise, if you do not have that requirement, always use pass by pointer(*), pass by reference(*) or pass by value(*)
(*)(depending on if you want to modify the original variable).
|
|
|
|

|
The suggestion for an alternative
int* func()
{
....
return new int;
}
represents a memory leak, unless the caller eventually deletes the int.
This is a poor alternative, and poor programming style.
Other than this, the article is good.
Tom
|
|
|
|

|
Hi hain,
It is the same with ptr-to-ptr and ref-to-ptr, For example, in COM, you call Release() to indicate you no longer need to use the interface pointer so that COM runtime can clean up if the reference count is zero. If you are using some library which uses ptr-to-ptr and ref-to-ptr, be sure to read the documentation carefully on what to do.
Best Regards
CBasicNet
|
|
|
|

|
The concern I have for References is that while it is perfectly clear at the time you write the function, a year later when you come back to that function (or someone who didn't write it needs to modify it), it is not as clear. This is particularly true in a lengthy function where the function parameters may not be visible on your screen while you are modifying the function body. The result is that you might think you are modifying a local variable/pointer, rather then modifying the caller's data. While I certainly appreciate the coding convenience of using references, I'd just as soon not open up the possibility of creating a bug later in the project, no matter how slight that possibility.
|
|
|
|
|

|
There are of course many trade-offs. One of the advantages of references that I like is that if a parameter cannot be null, a reference gets the compiler to enforce this condition. Better to let the compiler do the work than write a bunch of error handling code, I always say.
Brad
|
|
|
|

|
good point!
from,
-= aLbert =-
|
|
|
|

|
It depends on the programmers you have.
A good programmer will do proper housekeeping, and do not unnecessarily modify parameters passed to function he writes.
A bad one will always find a way to break your code. C++ provides tens of features for one to shoot himself in the foot.
|
|
|
|

|
utter fizzle-fuzzle! I've seen these so-called "good" developers shoot themselves in all three feet whilst skinning the proverbial cat... heck I'm one of them!
|
|
|
|
 |
|
|
General News Suggestion Question Bug Answer Joke Rant Admin
Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.
|
Explains the reason behind using pointer-to-pointer and reference-to-pointer to modify a pointer passed to a function.
| Type | Article |
| Licence | CPOL |
| First Posted | 31 Aug 2003 |
| Views | 389,175 |
| Bookmarked | 75 times |
|
|