Click here to Skip to main content
16,022,362 members
Please Sign up or sign in to vote.
5.00/5 (2 votes)
See more:
hi, i've just been playing around strings and different uses for them and whatnot, and then i stumbled upon a weird anomoly. I got it in my head that it might be useful at some point to pass a string into a function as a reference parameter so you can just call a function that fills a string. Well, a reference parameter is basically just a pointer to the variable being passed and then every usage of that variable within a function is actually a dereferenced pointer right? well, strings are already pointers to the first character in the array of characters. so i figured, why can't you just pass the pointer and then change the value of the string like so:


C++
#include <windows.h>
#include <iostream>
using namespace std;

void pass(LPTSTR herp);

int main (int argc, char * argv[])
{
	TCHAR herp[1024] = "";
	pass(herp);
	cout << herp << "   " << strlen(herp) << "\n";
	system("PAUSE");
        return 0;
}


void pass(LPTSTR herp)
{
	herp = TEXT("blah blah blah");
	cout << herp << "   " << strlen(herp) << "\n";
}


Here, i just passed the char* herp, and then tried to change it's value within the function. which worked! when i cout within the function, herp is indeed "blah blah blah" and contains 14 characters. but then, when the function ends, and the main resumes, and i cout there, herp is empty with 0 characters. So i just figure that when the function ends, it just clears the memory that was allocated during the lifetime of my pass function. So, the question, is there anyway to make the memory allocated during the pass function, stay there throughout the lifetime of my main function?

EDIT: weird, can't figure out why the c++ formatting hates that code. ah well, you get the picture.
Posted
Updated 3-Sep-11 16:35pm
v6
Comments
Simon Bang Terkildsen 3-Sep-11 22:36pm    
Yeah the editor doesn't like < and > so you'll have to use &lt; and &gt;
OldTimer2 10-Sep-11 21:09pm    
+5

You are mixing up the "value of the pointer" versus the "value of what the pointer points to".

In your pass function, the declaration of LPTSTR herp is essentially TCHAR *herp. Inside the pass() function, a local value of the pointer is on the stack, the statement herp = TEXT("blah blah blah"); stores a pointer to the string "blah blah blah" in the local copy of herp. The pointer (also named herp) in the main() function is not affected by this change and that's why you see the results you see.

If you really want to change the value of the pointer herp in the main code, you need to de-reference the pointer one more time.
*herp = TEXT("blah blah blah");
and this only changes value of the pointer, not the contents of the TCHAR herp[1024] = ""; array of chars.

If you intent is to actually change the content of the buffer itself, then you have to copy the characters into the array with something like strcpy(herp, TEXT("blah blah blah");, in other words, use the incoming pointer to point to the destination of a string copy function.

Protecting against overflowing the buffer is an exercise for the student.
 
Share this answer
 
Comments
OldTimer2 10-Sep-11 21:09pm    
+5
The code below would do what you're after.
C++
void pass(TCHAR** herp)
{
    delete[] *herp;
    *herp = TEXT("blah blah blah");
    cout << *herp << "   " << strlen(*herp) << "\n";
}
 
int main (int argc, char * argv[])
{
    LPTSTR herp = new TCHAR[1024];
    pass(&herp);
    cout << herp << "   " << strlen(herp) << "\n";
    system("PAUSE");
}


It's been almost 10 years since I worked with C++, so my C++ terminology is bad to say the least, so I have trouble explaining what the problem is with your code, but here goes.

When you define herp like this TCHAR herp[1024] = ""; you cannot change the address as it's a non-modifiable lvalue. So you'll need to rewrite it to a pointer LPTSTR herp = new TCHAR[1024];

In the pass function you take an address to the actual string, you'll need to get the address of to the pointer you wish to change. you get the address of a pointer by using &. So in order to pass the address of the herp pointer to the pass function you'll write pass(&herp)

If you have any question feel free to ask and I'll try to explain in more detail if I'm able to :) If I'm not able I'm sure that some of the great guys who frequent the Q&A will be able to.
 
Share this answer
 
v2
Comments
FatalCatharsis 3-Sep-11 22:52pm    
interesting! this is alot like something i originally tried to do. i was trying to make it work like a normal reference parameter where the function prototype was:

void pass( TCHAR* & herp);

which wouldn't compile when using TCHAR herp[1024] = ""; . I took your "new" statement there and used it with that prototype that i wrote there, and it worked just fine without all the dereference operators :P. but now i'm curious, because i havn't actually gotten far enough into c++ to learn new and delete, and have no idea what's going on. what is a non-modifiable |value? that is the same thing the compiler told me, and i wish to know what being dynamically allocated memory changes. why can one use the (=) operator and one cannot?
Chuck O'Toole 3-Sep-11 23:15pm    
I'm a bit leary of this solution, the "delete []*herp;" statement deallocates the memory allocated in the main function but doesn't allocate anything new. It seems to work because you are not really moving data into the buffere anyway as the next statement "*herp = TEXT(......)" only changes the pointer's content, not the buffer the original value of the pointer pointed to (only one de-reference to a "TCHAR **" type only gets to the pointer itself). See my Solution 2
Simon Bang Terkildsen 4-Sep-11 0:04am    
A vote of two I believe is very harsh, as you're saying the answer is not correct. The only thing you put a finger on is that there is not allocated new memory in pass so what?
If I understand the rest of what you're saying, then you're saying the code doesn't change the value of the allocated memory in main (e.g. by using strcpy), and that is Exactly the point, I'm sure the OP knows about strcpy and the question is about why the address of the original pointer didn't change.

From what I see the only thing your solution mentions that I haven't already is strcpy which I didn't mention becuase I don't read this question as a how do I copy a string to another string.
Chuck O'Toole 4-Sep-11 0:08am    
The very last sentence in the OP's question was "and then change the value of the string like so:". Clearly he wanted to change the string, not the pointer. Your solution does not address that. I don't believe it is a safe assumption that the OP knows about strcpy, clearly he thinks that the statement in pass() will change the "string" (i.e, the buffer) where it clearly won't. Your solution also shows the bad practice of deallocating memory in a function that doesn't allocate. If that's meant as a teaching solution, it's not a good one. Therefore, 2.
Simon Bang Terkildsen 4-Sep-11 0:57am    
"and then change the value of the string like so:" is not the very last sentence, you're missing an entire paragraph. Even if strcpy was what the OP were looking for it does not hurt in anyway to enlighten him about why what he tried didn't work, on the contrary.

Deallocating memory in a scope where it wasn't allocated is bad practice, agreed, but not wrong. If I hadn't deallocated the memory then someone would be here complaining that the memory wasn't deallocated, you probably would.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900