Many Win32 API functions have parameters specified to be "out". For example, GetIconInfo() description says about the second parameter that The function fills in the structure's members.
This implies that the function doesn't ever read the original values stored in the "out" parameter - only changes them - and therefore the caller is free to skip initialization.
Yet in one project I see the following:
ICONINFO ii;
::SecureZeroMemory(&ii, sizeof(ICONINFO));
if (::GetIconInfo(hIcon, &ii))
{
//do stuff, then
//release bitmaps
if(ii.hbmMask)
::DeleteObject(ii.hbmMask);
if(ii.hbmColor)
::DeleteObject(ii.hbmColor);
}
Is there any sense in that SecureZeroMemory() call? What could happen without it?
Well, in general I think initialisation is not needed, but good practice if you don't know exactly what the called function does with the values in the output variable.
In this specific case, the ICONINFO structure has two HBITMAP members which are essentially pointers to bitmaps. In the general case I'd say that if you are passing pointers to a function then you have to be certain that:
You pass in pointers that point to nothing and the
function you call creates the thing
pointed to for you and makes sure
your pointer points to it. (and probably leaves you to manage the newly allocated stuff) or
You pass in a pointer that points to
something (i.e. you allocated something for it) and the
function uses what you allocated.
The GetIconInfo() function fits the first case. So for clarity and perhaps even security it looks like a good idea to me to ensure the HBITMAP members of the ICONINFO structure are actually zero, rather than a random value that can lead to all kinds of nastiness further down the road.
So my verdict in this case would also be: not necessary but good practice.
Nothing. I mean if one is pretty sure that whatever is written there before call is discarded then there is no reason for doing that. But we don't know how internally the API will
function unless we developed the API, then it would be a good idea to initialize it.
This implies that the function doesn't ever read the original values stored in the "out"
parameter - only changes them - and therefore the caller is free to skip initialization.
Perhaps it isn't about the function reading the fields. Maybe its for detecting fields unfilled by the function? I don't know if this is necessary in this case, just pointing out that it might not be about reading.
Related
I'm getting to grips with references in C++ and I have a small query surrounding references & scoping, for this it's probably best to create an example:
Imagine I have a method in "BankDatabase.cpp" which takes a bank record by reference and adds it to a data structure (also by reference).
void AddRecord( BankRecord& bankRecord )
{
//Add record to data structure by reference
}
If I run a method like so:
void TestAddRecord( BankDatabase& bankDatabase )
{
BankRecord bankRecord { "John", "Doe", 9999 }
bankDatabase.AddRecord( bankRecord );
}
To my mind, "bankRecord" falls out of scope (as do its two strings and int) and is thus cleared from memory at the end of the "TestAddRecord" method, leaving "bankDatabase" pointing at some empty memory?
If so what's the general accepted standard / resolution to such a scenario? It seems a little mad to have to pass things by value...
In that case passing by value seems like the way to go. Allocating a new BankRecord pointer will work too. Storing things by reference is not very great.
However if I'm not mistaking, your two strings and the int won't be lost since they are present in the stack and will not be deallocated. But bankRecord will still be lost.
The best way to answer these concerns is to step through the code in the debugger and see what the Vector is doing with the variable being appended. Look especially at the constructor calls as you step into the data structure's Append functions. Because I do not know your underlying data structure, it is a bit more difficult for me to tell you more information. I will assume it is a std::vector for now until told otherwise.
You may be surprised to learn that references passed through a function do not tell the entire story about when it will go in and out of scope. I often think of C++ references as pointers that do not need nullptr checks.
Your code will work fine as long as the reference is copied into the vector or does not go out of scope because the variable it pointed to was destroyed. The reference will not go out of scope if it is referring to a member variable or memory on the heap for your particular case.
If the reference was declared on the stack to a variable created on the stack, and then appended to the vector, then you will have scope problems.
You should also look into emplace() if you have C++11 and the compiler supports move semantics.
In short, the most important thing you can do here is step through the code and see what Constructors are being called. This will give you the answer you desire.
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?
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.
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.
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*?
I have noticed that most C++ experts always advice it's better to pass by value, due to RVO. This allows me not worry too much about pointer manipulation and is easier to write code as well. No complaints there. This makes me wonder whether it is the correct approach to not use dynamic memory allocation (on the heap) at all and always pass parameters and return results by value?
This means instead of coming up with signatures like this:
Character* getCharacter(Sprite *sprite, Action* action)
I should more or less stick to signatures like:
Character getCharacter(Sprite sprite, Action action)
Is my understanding correct? or did I juth think i thaw a putthy cath?
They each have there pro's and con's. remember that using words like "always" is an absolute. Only the Dark Side deals in absolutes.
So let's look at each way and when we would use them.
Pass by value is good when the object being passed is smaller (since a local copy gets made). It is also good if you want to be sure to not accidentally change the original data. Its shortcoming is it makes a local copy and that can be bad if it is really big.
Pass by reference only passes a memory address. Therefore, large objects can be passed for a relatively low footprint. Also, with a reference, you can modify the original (this is both good and bad). This enables you to "return" more than one variable (so to speak). So obviously, the big con here is that you can mistakenly change the original data.
Constant pass by reference is generally accepted to be a very strong candidate for doing things. It has the pros of both pass by reference and value. Low footprint since it is a reference AND you can't change the original. There aren't many cons accept for the fact that your use of the variable in the method needs to change a little. Remember, its a const and therefore cannot be modified in the function.
Remember, there is no magic-bullet. Nothing is always better. Determine what you need and select the right tool for the job.
EDIT: also, has been said. Passing is not the same as dynamic allocation. dynamic allocation only happens with the "new" keyword. My suggestion would be to avoid the "new" keyword for now until you have a better understanding of arguments and pointers.
Whether or not you allocate an object on the heap typically is driven by one of the following concerns:
If the new object needs to outlive the function that creates it, the object must be allocated on the heap.
If the object is very large, and does not fit on the stack, then you must allocate it on the heap.
Beyond that, the choice of pass by value or pass by reference is determined by the semantics. If you want to operate on a copy, pass by value. If you want to operate on the actual object, pass by reference.
Your statement is simply utterly untrue. There is some light advice to pass by value instead of the mainstream const-ref in the special case where the function will copy the argument to a local variable anyway.
And for passing by-nonconst-pointer, pass by value was never an alternative. The first implies an optional out or inout param and the second and input param.
And mentioned dynamic allocation in question title just fits no way with the content.
Your understanding in definitely not correct.
I have been writing a program that has a rather large structure that is passed by reference to a few functions. However, there are a few other functions that need access to small pieces of information within the large structure. It's not being edited, just read.
I was thinking of creating a a second structure that just copies the specific pieces of information needed and passing that by reference, rather than passing the entire structure by reference.
What I am wondering is two things:
Since I am passing the large structure by reference, there really is no performance impact. Correct?
Even if 1) is correct, is it bad practice to be passing around a structure that shouldn't be edited (even though it wouldn't be edited, but still I'm talking about the principle here).
More specifically:
I have a configuration structure that sets up the programs configuration by calling a function and passing the structure by reference. There is some information (process name, command line arguments) that I want to use for informative purposes only. I'm asking if it's bad practice to pass around a structure that wasn't meant for the purpose of what I want to use it for.
1) Since I am passing the large structure by reference, there really is no performance impact. Correct?
Correct.
2) Even if 1) is correct, is it bad etiquette to be passing around a structure that shouldn't be edited (even though it wouldn't be edited, but still I'm talking about the principle here).
You could let your function accept a reference to const to make sure the function won't alter the state of the corresponding argument.
I'm asking if it's bad practice to pass around a structure that wasn't meant for the purpose of what I want to use it for.
I'm not sure what you mean by this. The way you write it, this definitely seems to be a bad practice: you shouldn't use something for doing what it wasn't meant for. That means distorting the semantics of an object. However, the rest of your question doesn't seem to imply this.
Rather, it seems like you are concerned with passing a reference to a function because that may allow the function to alter the argument's state; but provided the function takes a reference to const, it won't be able to alter the state of its argument. In that case, no it's not a bad practice.
If you are referring to the fact that the function only need to work with some of the data members or member functions of your structure, then again that is not necessarily a bad design. It would be silly to require that each function access every member of a data structure.
Of course, this is the best I can write without knowing anything concrete about the semantics of the function and the particular data structure.
Correct.
Pass it by const reference; you'll get the performance gains of pass-by-reference withoug allowing editing.
By the way, if only a fraction of the "big structure" is required to that function it may be an indicator that such fields store some information "on their own" - i.e. the rest of the "big struct" is not needed to interpret them correctly. In this case, you may consider moving them to a separate struct, that will itself be a member of the first "big struct".
As one step further, you can keep such configuration objects in a shared pointer and pass it anywhere you want and so you dont have to worry about ownership of the structure. In this way you ensure that a single original configuration object is shared by the all program components
Like others have said, use const.
If you are doing C++, access those small pieces of information with accessor functions. Then functions that don't need to change the state of your struct will not have to touch any member fields, only member functions.
As others have mentioned, const& if you aren't modifying the data.
However, your point about "should I copy the data to a smaller struct" has mostly been glossed over. The answer is "maybe".
A good reason not to do it is that it is a waste of time -- literally, it costs time to copy stuff around.
A good reason to do it is that it reduces the effective state of your subprocedure. A subprocedure that doesn't access global variables (and hence global state), and isn't passed any pointers, has a very limited state. Procedures with limited state are easier to test, often easier to understand, and usually easier to debug.
Often you want to call each function with the absolute least amount of data required for that function to solve the problem it has. If you avoid passing in a "pointer to everything" (and references are pointers) to every function, you can maintain this rule, and it can often result in code that is easier to maintain.
On the other hand, stripping the data out of the big monolithic state and into small local structs can contain bugs and errors.
One way to avoid this problem entirely is to avoid the big monolithic state object with parameters all mixed together, and if there are some parameters that are bundled together to answer some questions, they should be in their own sub-struct to start with. Now calling the subprocedure is easy -- you pass in the sub-struct which already has the parameters bundled.
I have an object which implements reference counting mechanism. If the number of references to it becomes zero, the object is deleted.
I found that my object is never deleted, even when I am done with it. This is leading to memory overuse. All I have is the number of references to the object and I want to know the places which reference it so that I can write appropriate cleanup code.
Is there some way to accomplish this without having to grep in the source files? (That would be very cumbersome.)
A huge part of getting reference counting (refcounting) done correctly in C++ is to use Resource Allocation Is Initialization so it's much harder to accidentally leak references. However, this doesn't solve everything with refcounts.
That said, you can implement a debug feature in your refcounting which tracks what is holding references. You can then analyze this information when necessary, and remove it from release builds. (Use a configuration macro similar in purpose to how DEBUG macros are used.)
Exactly how you should implement it is going to depend on all your requirements, but there are two main ways to do this (with a brief overview of differences):
store the information on the referenced object itself
accessible from your debugger
easier to implement
output to a special trace file every time a reference is acquired or released
still available after the program exits (even abnormally)
possible to use while the program is running, without running in your debugger
can be used even in special release builds and sent back to you for analysis
The basic problem, of knowing what is referencing a given object, is hard to solve in general, and will require some work. Compare: can you tell me every person and business that knows your postal address or phone number?
One known weakness of reference counting is that it does not work when there are cyclic references, i.e. (in the simplest case) when one object has a reference to another object which in turn has a reference to the former object. This sounds like a non-issue, but in data structures such as binary trees with back-references to parent nodes, there you are.
If you don't explicitly provide for a list of "reverse" references in the referenced (un-freed) object, I don't see a way to figure out who is referencing it.
In the following suggestions, I assume that you don't want to modify your source, or if so, just a little.
You could of course walk the whole heap / freestore and search for the memory address of your un-freed object, but if its address turns up, it's not guaranteed to actually be a memory address reference; it could just as well be any random floating point number, of anything else. However, if the found value lies inside a block a memory that your application allocated for an object, chances improve a little that it's indeed a pointer to another object.
One possible improvement over this approach would be to modify the memory allocator you use -- e.g. your global operator new -- so that it keeps a list of all allocated memory blocks and their sizes. (In a complete implementation of this, operator delete would have remove the list entry for the freed block of memory.) Now, at the end of your program, you have a clue where to search for the un-freed object's memory address, since you have a list of memory blocks that your program actually used.
The above suggestions don't sound very reliable to me, to be honest; but maybe defining a custom global operator new and operator delete that does some logging / tracing goes in the right direction to solve your problem.
I am assuming you have some class with say addRef() and release() member functions, and you call these when you need to increase and decrease the reference count on each instance, and that the instances that cause problems are on the heap and referred to with raw pointers. The simplest fix may be to replace all pointers to the controlled object with boost::shared_ptr. This is surprisingly easy to do and should enable you to dispense with your own reference counting - you can just make those functions I mentioned do nothing. The main change required in your code is in the signatures of functions that pass or return your pointers. Other places to change are in initializer lists (if you initialize pointers to null) and if()-statements (if you compare pointers with null). The compiler will find all such places after you change the declarations of the pointers.
If you do not want to use the shared_ptr - maybe you want to keep the reference count intrinsic to the class - you can craft your own simple smart pointer just to deal with your class. Then use it to control the lifetime of your class objects. So for example, instead of pointer assignment being done with raw pointers and you "manually" calling addRef(), you just do an assignment of your smart pointer class which includes the addRef() automatically.
I don't think it's possible to do something without code change. With code change you can for example remember the pointers of the objects which increase reference count, and then see what pointer is left and examine it in the debugger. If possible - store more verbose information, such as object name.
I have created one for my needs. You can compare your code with this one and see what's missing. It's not perfect but it should work in most of the cases.
http://sites.google.com/site/grayasm/autopointer
when I use it I do:
util::autopointer<A> aptr=new A();
I never do it like this:
A* ptr = new A();
util::autopointer<A> aptr = ptr;
and later to start fulling around with ptr; That's not allowed.
Further I am using only aptr to refer to this object.
If I am wrong I have now the chance to get corrections. :) See ya!