|
Yes to all. I know that about the BFFM_INITIALIZED. I even tested to save the hwnd into a global variable where I made the regular call at the BFFM_INITIALIZED(the one that works) (inside the BrowseCallbackProc) and used this global variable to send a message on button click.
|
|
|
|
|
I'm passing a pointer to an object into a function where I would like to validate it. I remember seeing a simple typecast used to do this, but I cannot remember exactly how it was done. My attempt returns the same pointer even though it is totaly bogus.
CImage *tmp = dynamic_cast<CImage*>(cImage);
if ( tmp )
{
m_ImagePtr = tmp;
}
|
|
|
|
|
So what exactly is the problem? What is cImage ?
waldermort wrote: I'm passing a pointer to an object into a function...
What function?
waldermort wrote: My attempt returns the same pointer...
What exactly does this mean?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
CImage is a class. Perhaps if I show the full function.
bool CImage::SwapImage( CImage *cImage )
{
CImage *tmp = dynamic_cast<CImage*>(cImage);
if ( tmp )
{
m_ImagePtr = tmp;
return true;
}
return false;
}
I'm testing the call like this
CImage::SwapImage((CImage*)0xffffffff);
Which results in the value of tmp being 0xFFFFFFFF, whereas I want it to bu NULL.
I should also point out that I need to test the pointer using a similar method in the case that the provided pointer is no longer available. ie.
void CImage::Draw( HDC hdc )
{
CImage *tmp = dynamic_cast<CImage*>(m_ImagePtr);
if ( tmp )
return m_ImagePtr->Draw(hdc);
|
|
|
|
|
waldermort wrote: Which results in the value of tmp being 0xFFFFFFFF, whereas I want it to bu NULL.
As it should. Your if-statement is checking against a non-zero value, so your pointer will be set to 0xffffffff and the function will return true. If you want to check it against valid values, you need to specify what those are in the if-statement (or rather, what values are invalid).
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
I understand that, but all I need to do is assert that the cImage pointer is pointing to a valid CImage instance (ie. it has not been destroyed). I was hoping that the dynamic_cast would return NULL if the pointer is not valid, but this doesn't seem to be the case.
|
|
|
|
|
If CImage is a class of your own making, then you have control over whether it contains valid data or not. Much like COleDateTime has a GetStatus() method, you can employ the same thing.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
The question is simple, regardless of the type of pointer, how can you test it is still pointing to a valid location and not since gone out of scope?
I am passing a pointer to a class. The class will store the pointer and later call methods from the pointer. If I pass in a pointer, then delete the memory it's pointing to, then try to call those methods, the program will crash, even though the stored pointer is holding what it thinks is a valid address. There must be a simple way to test a pointer.
|
|
|
|
|
waldermort wrote: The whole point of my question is to find out how to correctly validate that a pointer is poining to a certain type...
Then use IsKindOf() .
waldermort wrote: ...the docs say that if dynamic_cast fails it returns NULL...
Right, but it has no way of knowing if your CImage object is valid or not. A pointer value of 0xffffffff is valid.
waldermort wrote: If I pass in a pointer, then delete the memory it's pointing to...
After deleting, you must also assign NULL to the pointer. Anything short of this is just asking for trouble.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
IsKindOf() is MFC only, which unfortunatly I am not using. I can see why dynamic_cast is failing, simply because it should be used to convert one type to another, not for validation like I am trying to do. I usually always assign NULL to a pointer both on creation and deletion, but in this case it's not possible. I must test the pointer somehow before trying to use it.
|
|
|
|
|
waldermort wrote: IsKindOf() is MFC only, which unfortunatly I am not using.
What about typeid() ?
waldermort wrote: I usually always assign NULL to a pointer both on creation and deletion, but in this case it's not possible. I must test the pointer somehow before trying to use it.
Can you modify the CImage class?
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
type_info and typeof both return char pointer to the type name associated with the pointer, they do not perform any pointer validation. Unfortunatly it looks like I am going to have to rethink this. Yes, I can modify the CImage class.
CImage is a base class which holds and draws a series of DIB sections. My basic idea is to give the class the ability to draw the image contained within another instance of the class (a little like swapping the this pointer). Since the drawing functions will be called often, I would prefer to store the pointer, that way I only need to change the image once rather than passing a pointer for each bitblt call.
|
|
|
|
|
The pointer is valid, the object it is pointing to is not. What you can do is add a static method to cImage to check the status of a pointer you pass to it to see if it is a valid object of that type.
If you decide to become a software engineer, you are signing up to have a 1/2" piece of silicon tell you exactly how stupid you really are for 8 hours a day, 5 days a week
Zac
|
|
|
|
|
waldermort wrote: Which results in the value of tmp being 0xFFFFFFFF...
Of course it does. Why would it be anything else? It should retain that value until it is assigned something different.
waldermort wrote: ...whereas I want it to bu NULL.
Then you can't call SwapImage() with a non-NULL value.
"Approved Workmen Are Not Ashamed" - 2 Timothy 2:15
"Judge not by the eye but by the heart." - Native American Proverb
|
|
|
|
|
DavidCrow wrote: Of course it does. Why would it be anything else? It should retain that value until it is assigned something different.
The whole point of my question is to find out how to correctly validate that a pointer is poining to a certain type, NOT to find out how large your ego is! If I knew it would give me those results I would not have used it in the first place now would I? I am testing for NULL because the docs say that if dynamic_cast fails it returns NULL and throws an error, it seems logical to me that if the return value is not NULL then the provided pointer is valid.
|
|
|
|
|
I think you are over complexifying things.
unless don't know where m_ImagePtr some from or where the input to SwapImage come from, you don't need to test the validity of the pointer except for NULL.
waldermort wrote: CImage::SwapImage((CImage*)0xffffffff);
This is weird coding; I assume 0xffffffff is here only to show what your are trying to explain ?
me think that if you don't know where and how your data come from, you'd better review your whole system.
bool CImage::SwapImage( CImage *cImage )
This should only receive a CImage object and it should only check for NULL.
CImage *tmp = dynamic_cast<CImage*>(m_ImagePtr);
if tmp is ever NULL when m_ImagePtr is not then you better check your code; because it shows that you are assigning untyped data to something that needs to be types, either by using a C cast or by directly casting an adress.
|
|
|
|
|
the 0xFFFFFFFF is there just to represent an arbitary pointer that is not of the CImage type. I understand what you are saying. The CImage class is part of a library that I may use again and again, I want to put this test in place for two reasons
1. To detect hanging pointers. In the case a CImage class was instantiated using new , passed in then delete d.
2. To prevent typecasting of other data types being passed in, which would again throw an error.
I think I am going to have to do this through smart pointers and reference counting.
|
|
|
|
|
There is no way to what you are trying to do. dynamic_cast is used to upcast or downcast through base classes and derived classes, and makes sure that the cast is valid, not checking whether the pointer is a valid address. Look it up in MSDN, there is a very good list of examples there.
You may be right I may be crazy -- Billy Joel --
Within you lies the power for good, use it!!!
|
|
|
|
|
Yeah, I kinda learnt that the hard way tonight
But your post just gave me an idea. I may be able to derive CImage from an empty base class and type cast to that. I will give it a try now.
-- modified at 15:31 Thursday 2nd November, 2006
That didn't work either, the address returned is simply an offset of the origional. Oh well, back to reference counting.
|
|
|
|
|
Garbage in, garbage out. You have to start with a valid C++ object for dynamic_cast to work.
|
|
|
|
|
I agree. But there is no way to detect garbage. It wouldn't be so bad if I could throw an error when trying to dereference the pointer, but I have found no way to detect it before the OS does.
|
|
|
|
|
waldermort wrote: But there is no way to detect garbage.
you are the one who do the coding, you have to make sure there is no garbage that is introduced to the system.
If there are places in your code that can generate garbage, fix them.
in your example, the CImage class must be instantiated somewhere, if you cannot validate the construction of your own object, you have a problem with your design.
remember that C++ is quite "type" safe; and with the compiler warnings set to level 4 you should be able to resolve all of these without having to do dark magick incantations on your pointers.
and try to never do C type casting on C++ objects, use static_cast<CImage*>(pointer) instead of (CImage*)pointer
|
|
|
|
|
Maximilien wrote: you are the one who do the coding, you have to make sure there is no garbage that is introduced to the system.
I am the one coding this library, that is true, but I am not the onw who will coding the final product. This project is a re-usable library which I and other developers may use, therefore I want to prevent/detect garbage from being entered into my code.
|
|
|
|
|
You can wrap the dereference in a SEH block, that will let you handle the access violation if it occurs.
|
|
|
|
|
waldermort wrote: I'm passing a pointer to an object into a function where I would like to validate it.
If by "validate it" you mean make sure it is pointing to a valid object, there is no way you can do it with C++.
Can you use a reference-counted smart pointer instead of a "raw" one?
|
|
|
|