5

I have to admit this has always confused me how certain windows API accept strings. Take for example SetWindowText(). Now any function which takes a pointer to anything typically means it doesn't store that object but merely use the pointer that is passed. Therefore the caller has the responsibility to make sure the object passed to it exist for whenever it may be needed. Now what would you expect the final message that will be printed out below?

TCHAR * label = new TCHAR[50]();
_tcscpy( label, _T("allocated string") );
m_wndStaticLabel.SetWindowText( label );
_tcscpy( label, _T("string has changed") );

Theoretically I would expect it to print "string has changed" but it prints "allocated string". Similarly:

CString label = _T("CString Label");
m_wndStaticLabel.SetWindowText( label );

In this case a pointer of a local variable 'label` is being passed to it but still no problem. The control always prints the right string even though it received pointer of string allocated on stack.

This implies that the control actually allocate its own memory and assign that to the control instead of the pointer we are passing but this fact is never documented. Isn't this a little misleading? When I am passing a pointer to a function, one thing I immediately remind myself is I shouldn't be destroying it until the function returns but it is not the case in this case and it is not documented either.

So my question ultimately is this simply lack of documentation or there is something else to it when we passing a pointer to an object but it essentially behaves like we have passed object by value?

2
  • 2
    An operating system that would rely on a program to keep a pointer stable beyond an api call would be pretty unreliable. There are way too many ways to get the program to corrupt it. So it doesn't work that way, it copies the string. Commented May 1, 2014 at 16:42
  • "I shouldn't be destroying it until the function returns" You didn't destroy it. You gave the function a pointer, it made a copy of the string, then it returned, then you changed the content. Commented May 1, 2014 at 17:04

3 Answers 3

7

Remember that the Windows API is based on C conventions. This means that the only way to pass a string is as a pointer to the first character. None of the functions accept a CString or std::wstring for example, except by implicit conversion to a const wchar_t *.

You are right to be concerned about whether a copy of the pointer is retained by the control, but rest assured that it doesn't. The documentation doesn't mention this, it's assumed by default - if the pointer was retained, there would be a note about it. You'll find that some handles are documented in this manner.

Sign up to request clarification or add additional context in comments.

Comments

3

I think all windows API functions that take pointers will only use the pointers while running, but never store them (except for special documented cases). When the data is needed later, a copy is made.

The problem if a function would store the pointers would be that the system is taking ownership of the objects, and thus would be responsible for freeing them. But then the functions would need to know how the objects were allocated - there are many possibilities.

I usually also adhere to this principle in my own functions.

Comments

0

In C++, arrays decay to pointers when passed as function arguments, so the prototype is exactly as it should be -- a pointer to a TCHAR. Otherwise, how do you suggest the function prototype for SetWindowText() be written?

In addition, look at your code sample. You overlooked the _tcscpy() function and concentrated solely on SetWindowText(). Given your reasoning, how is _tcscpy() supposed to behave when given a TCHAR*?

3 Comments

If at least they document it than I will be sure I can destroy the pointer after I have passed to the function. _tcscpy doesn't keep its own copy of the string as far as I can tell, it just works with the pointers that I pass.
I can tell you that any documentation that goes and tells the programmer "we will not keep the pointer" would look amateurish. All experienced C++ programmers know that for strings, pointers are not "kept", and if they were, it would be so anomalous that it has to be documented.
I think this depends on the context and it probably can not be the rule. The reason I asked question was also because recently I am thinking in OOP & design patterns and when you pass a pointer to another object, a relationship is created. One object now may need the other. However Windows APIs are C style and relationship exist only for the duration of the function. This distinction helped me appreciate why they work they way they do.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.