I'm working with C++ unmanaged, the problem that I have happens when I call a method that returns an LPVOID.
LPVOID MyMethod(...);
The problem is that this method sometimes returns a Bad Ptr and I want to know if there is a way of detecting this, if the value returned is a Bad Ptr.
I have tried asking if it is NULL with no luck.
The only way in which I realize if the result is a Bad Ptr is while I'm debugging, I have tried some different ways but still unable to do it.
No, there is no easy way to determine if a pointer is bad.
Windows does have IsBadReadPtr, IsBadWritePtr. These functions are inherently flawed - they only determine if a function is readable or writable in your address space at the moment of the call. They can also be the cause of security issues and should never be used.
The main issue is that there is no way to differentiate between a "bad" pointer that is still accessible to your process, and a good pointer.
For instance,
int g[5];
int somethingElse;
void* GetPointer()
{
return &g[5]; // Whoops, off by one.
}
&g[5] is probably a valid pointer in your process, and might be pointing to somethingElse, you'll be able to access it without crashing but writing to it will corrupt your state.
Your real problem is that you're calling a function that returns bad pointers. Do you have access to its source code? 90% of the time I've encountered problems like this, it's because either:
1) The function is returning a pointer to the stack; e.g.,
char a[10];
...
return a;
2) The function is returning a pointer that was never assigned valid memory to begin with:
char* foo; // Invalid pointer
...
return foo;
3) The function is returning a pointer that was already deleted (or free'd):
char* foo = new char[10];
...
delete[] foo;
return foo;
You really need to find the real problem, rather than work around it.
LPVOID is a typedef to a pointer to void, Visual studio typically displays NULL values as "bad pointer" in the watch pane, are you sure that this pointer is not NULL?
No, you cant.
However, if you can create an auxiliary data structure to store locations and ensure you remove them from that auxiliary data structure when they get deleted (maybe add it to the destructor) you can check whether the pointers are in that structure before de-referencing them.
Related
I have a managed C++ wrapper class for a non-managed C library. I came across an issue where it seems that the pointer I am sending from my managed C++ class is not pointing to the same memory location which is used by the non-managed C code library method.
MyNonManagedType* dataPointer;
getDataFromNonmanagedCLibrary(dataPointer);
// this gives me junk data, where field should be a char array
String^ myFieldValue = gcnew String(dataPointer->field);
Is it possible that the dataPointer is not pointing to the same address used by the C library? Or maybe there is some kind of marshal method I need to use for this, or other pitfalls I may be missing?
If the pointer is not managed, given the code you have shown, there is no way for a C function to do anything with the uninitialized pointer except either:
Check it for NULL, and if so, do nothing with it, or
Use the address passed, and disaster happens.
You are passing the pointer by value, and passing by value means that the function will be using a local copy of the parameter that is passed, thus you see no changes when the function returns. The function cannot set the pointer and have those changes reflect back to the caller the way it stands now.
Since we're talking about a C interface, you should change the C interface to this:
void getDataFromNonmanagedCLibrary(MyNonManagedType**);
A pointer to the pointer is passed. Since we want to change the value passed to the function and have it reflect back to the caller, a pointer to the value is passed. Since the value just happens to be a pointer, we pass a pointer to the pointer.
Then you rewrite getDataFromNonmanagedCLibrary to initialize the pointer by dereferencing it:
void getDataFromNonmanagedCLibrary(MyNonManagedType** ptr)
{
*ptr = <the_address_you_expected_on_return>;
}
Then on the client side:
MyNonManagedType* dataPointer;
getDataFromNonmanagedCLibrary(&dataPointer);
Note that the address of the pointer is passed, no different than if you wanted to have a function change a non-pointer variable by passing the variable's address.
I'm using Visual Studio 2013 and C++11. I want to pass the address of a C++ object back to C. The C code will treat it as a opaque handle; C will never reference it. The only use will be to pass it back to C++ where it will again be used as a pointer to object.
I'm finding that if I create the object in C++ and pass it back to C, the object will be destroyed because it goes out of scope. As a work around, I created a global variable to hold the object so it won't be destroyed upon returning to C. What is the best practice? Should I use a ref-counted pointer type such as shared_ptr? How? I don't like the idea of casting to size_t or such.
The following is an attempt to demonstrate the question. Code won't work.
extern "C" _declspec(dllexport) void __stdcall SwbHttpListenW(const wchar_t *route, SwbHttpListen **listener)
{
*listener = &SwbHttpListen(route); // new will work but how about without new?
}
[Edited the code to re-ask for a solution not using new.]
How about heap allocating the C++ object using the new operator, and getting its address by using the ampersand (&) operator? By heap allocating the object, you ensure it will never be deleted until you actually use the delete operator on it, and the address could be stored/passed as an int.
A simple example:
int main() {
Person *a = new Person("Paul");
doSomething(a); //Passes the memory address of a to the function doSomething
//...and once you're finished using the object, you have to:
delete a;
return 0;
}
It's always going to be messy when you do this sort of thing, how you handle it really depends upon what you want the lifetime of your c++ object to be and, to a lesser extent, how you are going to get rid of it in the end. But clearly the c++ has to do any destruction, you cannot get the c to do that.
This sort of thing is an example of when it is not necessarily A Bad Thing to have global objects - though of course that means you cannot get rid of it freely. Alternatively, you could create it dynamically using new but you then will need an arrangement between the c and the c++ so that it gets deleted at the right time - you might end up with a global object pointer or maybe the c could pass the pointer back to get it destroyed - that would be the nicest solution.
Some trouble may be if some automated Garbage Collector are in use (it may be in C++). std::declare_reachable , std::undeclare_reachable may help.
Else the trouble really doesn't concern passing a pointer to C. And you need to develop some way to achieve a proper pointers to valid objects at the places where necessary... :-)
class A
{
private:
A(){};
~A(){};
public:
static A* GetInstance( void )
{
static A obj;
return& obj;
}
};
I was supposing if something bad happens would only happen at the first time, since the class constructor is only initialized the first time a call to GetInstance happens, I don't know the great depths of C++ and I do not trust C++, so when I need a pointer to this class that will be used many times in a function I'm currently doing:
A* ptr = A::GetInstance();
if( ptr )
{
Checking for the pointer validity, I believe that the method returns the address where the value of obj is stored so that ptr will point to it, which I guess it can't fail.
Please observe that I'm not talking about a small application, I'm currently developing on a 500,000+ lines MMO server application that handles thousand of clients and has to stay opened for weeks without crashing, defensive programming is the least minimum required. Is it for sure, 100% safe to use ptr without checking its validity?
There is certainly no way that that function will ever return a null pointer, so there's no point checking for that. It might make more sense to return a reference, to make it clear that it won't be null.
However, there's no guarantee that the function will always return a pointer to a valid object. If it's called from the destructor of a static object, then obj might already have been destroyed. This is one reason why globally accessible objects are a very bad idea, whether or not you wrap them up in the Singleton anti-pattern like this.
The function will always return a pointer to an object that exists. The only danger is if the object itself is invalid, and this should have been indicated by a throw from the object constructor. In your case you do not catch an exception from the constructor so the program should halt in that case, otherwise it should be good to go.
Checking for NULL is pointless because you always return a valid address.
Adding a check for the pointer is unlikely to cause significant performance degradation but should be unnecessary. Add it if it will make you feel better. However, I would be more concerned about buffer overflows, memory leaks and other more likely issues than whether the static keyword is implemented by the compiler correctly.
Suppose we have a situation like this. Suppose instead of "p = &global;" we called some function(written by someone which invalidate our pointer). How to handle this problem? How to protect code from crashes? I know about and use boost smart pointers. But what to do if we have this situation.
struct Test
{
int a;
int b;
int c;
};
Test global;
int main()
{
Test *p = new Test;
p->a = 1;
p->b = 2;
p->c = 3;
p = &global;
delete p;
return 0;
}
You handle it by fixing the bug and recompiling your program. Anything else makes no sense.
You can't and you shouldn't try to deal with this situation other then not letting it occur in the first place.
There are some basic rules in C++ that simply have to be obeyed.
Nothing. If you do this, then you get what you get. Don't do this.
Once you reassign p, you leak the Test object that p originally pointed at. You've now lost that memory for the duration of this app's runtime. Then when you delete a non-heap object, you're running into undefined behaviour and anything at all can happen (usually the runtime library will crash trying to delete non-heap memory - but you have no guarantees). There's absolutely nothing reliable that you can do once you've tried to delete non-heap memory.
You've already mentioned smart pointers, which is part of the solution. The other part is just being careful.
Unfortunately there's nothing you can do. The C++ compiler can't tell from your code whether or not you might delete a pointer in the future, so you have to be sure to manage them correctly in your code. This means that if you put the address of a non-heap-allocated item into a pointer, it's your responsibility nto to delete that pointer.
In short, C++ can't protect you from every possible mistake you can write.
You can use the code below to find out if a pointer points to a stack area or heap area:
bool IsMemoryOnStack( void* p )
{
void* dwStackTop = 0;
void* dwStackLowCurrent = 0;
__asm {
mov EAX, FS:[4]
mov dwStackTop, eax
mov EAX, FS:[8]
mov dwStackLowCurrent, eax
}
return ( p<= dwStackTop && p>= dwStackLowCurrent );
}
You need to swap the assignment and delete statements:
delete p;
p = &global;
BUT I would suggest never using the same variable to point at data that requires an explicit free and data that does not. Pick one or the other for each variable, so you can either always delete the memory before reassigning it or never delete it. If you try to keep track of how you're pointers got set, you'll wind up spending all your time whining about how C++ provides no memory management and forces you to write unmaintainable code.
The primary way to avoid this is to simply avoid using new or delete under any but the most tightly controlled circumstances.
Using new inside of main is particularly suspect -- the reason to use new in C++ is when you need to create an object that needs to outlive the scope in which it's being created (e.g., when you reach the end of that function, it must not be destroyed). In the case of main, the only reason to do what would be if you were allocating something in main that would not be deleted in main, but used by some the destructor of some global object as it ran after you returned from main (which is rarely done and even more rarely a good idea).
Most uses of new should be in the ctor of an object, and most uses of delete should be in the dtor of an object. If you have something like a collection, it can also make sense to use new and/or delete in some other member function(s) that handle(s) things like re-sizing the collection.
Other than that, there are entity objects that generally aren't ever assigned or copied. For example, consider a call routing system, where you create a "call" object when somebody dials their phone, and you destroy the object when they hang up. In nearly every such case, you have a global collection (or more than one) that holds pointers to these objects, so as soon as you create the object, its address goes into the (correct) global collection. Interesting point: nearly all code that I've seen where this pattern made sense did not have any external code that destroyed the object -- rather, the object itself was responsible for removing itself from the global connection, and using the (much argued-about) delete this; to destroy itself when the real-world connection (or whatever) it was attached to ended.
It is possible to overload delete. In theory you could have your overloaded delete refuse to do anything unless the address is valid. But how do you know if it's valid? The best you can say is "this wasn't allocated with new," but you'll probably have to overload new to do that.
For the record, the standard new and delete crash in this case because delete determines the address didn't come from new and assumes the worst. Assuming the worst is probably the best thing to do in that situation, though; at least it beats assuming the best.
So I'll second the advice to not protect against this in code, and simply don't do that.
My program is crashing every time I try to store a COM pointer into a struct, and then later try to use the original pointer. I don't have debug access to tell exactly what's wrong.
pRend->cp = cpRT;
ID2D1SolidColorBrush *scBrush;
ERF(cpRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::CornflowerBlue), &scBrush));
It crashes on CreateSolidColorBrush. However, if I comment out pRend->cp = cpRT, it doesn't.
By the way, pRend->cp and cpRT are of type ID2D1HwndRenderTarget *.
Instead of assigning directly QI and then store i.e.,
pRend->cp = cpRT;
should be replaced with
cpRT->QueryInterface(&pRend->cp);
It's unclear how much code exists between when you assign it into the struct and later use it in CreateSolidColorBrush. If it's a non-trivial amount of time, it's possible that you have a reference counting issue.
Are you storing a raw pointer in the struct? If so, switch it to a CComPtr and see if the crash goes away.
For instance. If you had the following type definition for the value of pRend (call it Render) and the value pRend was destroyed before making the CreateSolidColorBrush call, you could see this behavior.
struct Render {
ID2D1HwndRenderTarget *pCt;
~Render() {
pCt->Release();
}
};
As it turns out, I managed to stop the crashing by allocating pRend with malloc. This is not a problem because I will call free when I don't need it anymore. I'm interested in why calling malloc fixes this though. I'm used to just doing Datatype * var; and then just using var. Is that bad?
It's a smart pointer. I'm guessing you're inadvertantly calling release on it. In particular, it's addressof operator (unary op&) is overriden to call Release().
See what happens if you instead assign it to a reference, an ID2D1HwndRenderTarget*&.
Obviously, if you assign to a reference, you won't be able to reseat it.