|
Hi everyone,
I need some help with a design problem that I have. I am not exactly a software developer by profession, so I am hoping to get some suggestion from the experts here.
Well, basically I have 2 types of tracking systems (optical and sonar). So, basically I have an interface object and they both should inherit from it.
However, my problem is that they both take different parameters for initialization. So, if I have a method calloed Initialize, I cannot share it between then as they take different parameters for initializazion.
I was wondering what kind of design patterns you guys would recommend for developing objects that are of course same from a functional point of you, but differ internally quite substantially.
Thanks and cheers,
Keith
|
|
|
|
|
Hi,
do users set the parameters needed for initialization at runtime ?
We can do no great things, only small things with great love. - Mother Theresa
|
|
|
|
|
Normaly initialization only needs to be done when the object if first created, at which point in time you already know what type it is. Given that, use an abstract base class that only provides the interfaces they have in common and provide each derived class with an initialization function specific for that class. Do not make the initialization function part of the base class, because it only provides the interface that you need to access after initialization.
If for some reason you need to reinitialize the object thru a pointer to the base class (unusual). You'll need to know what all the derive classes are so you can use dynamic_cast<>() to downcast the base class pointer to one of the derived types. At which time you will know what type it is and what paramenters are required.
INTP
Every thing is relative...
|
|
|
|
|
|
This is quite common; the derived objects have their own constructors. They each can call the base constructor (or Init() function) with those parameters that are in common.
If the object has to be created early and then fully initialized later, you can create two virtual functions in the base object, one for each type. Yes, it's ugly, but I've done worse.
Anyone who thinks he has a better idea of what's good for people than people do is a swine.
- P.J. O'Rourke
|
|
|
|
|
Create parameter classes derived from a common base.
something like this
class TrackingParams
{
...
}
class OpticalTrackingParams : public TrackingParams
{
...
}
class SonarTrackingParams : public TrackingParams
{
...
}
class TrackingInterface
{
public:
virtual void Init(TrackingParams &);
};
class OpticalTracking : public TrackingInterface
{
void Init(TrackingParams & params)
{
OpticalTrackingParams & p = dynamic_cast<opticaltrackingparams &="">(params);
}
}
|
|
|
|
|
Im having a little trouble using free after a malloc.
Here is the malloc part:
GUIQueue* newMsg = (GUIQueue*)malloc( sizeof(GUIQueue) );
newMsg->data = (char*)malloc( sizeof(msg.u.reqvid) );
...
GUIQ.push( newMsg );
What i do now is pull the info from the queue (this is a MT'ed app.) and get the info and free the pointer.
GUIQueue* newMsg;
newMsg = (GUIQueue*)GUIQ.front();
GUIQ.pop(); // I know this looks weird, but pop doesnt return anything, so...
...
if( newMsg->data != NULL )
{
free(newMsg->data); // This first free causes the runtime error.
newMsg->data = NULL;
}
if( newMsg != NULL )
{
free(newMsg);
newMsg = NULL;
}
The error message that pops up is:
Unhandled exception at 0x7c901230 in LiteCycles.exe: User breakpoint.
I've cleared all my breakpoints, so i dont think it can be that, the stack looks like its deep in free and the last legiable method is _CrtIsValidHeapPointer.
Any ideas on whats causing this error? Any input is greatly appricated, thanks.
-Jader89
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
You are using either a class or a template that is called "GUIQueue".
Never mix C++ objects with malloc/free. Use new/delete instead.
Why? Because the object's constructor and destructor won't get called when you are using malloc and free.
What kind of errors you get depend on the C++ object you are using.
--
Roger
It's supposed to be hard, otherwise anybody could do it!
|
|
|
|
|
I tried switching to delete and new, but down the line of delete it still runs into the same method that free does, and cause the same error. Upon review of the last method, in the method header info, it says that it checks to see if the pointer is in the local heap, which i dont think it is in the local heap, cause its a different thread thats creating it, so this could be the main problem.
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
I'm not really familiar with multithreaded application, but I think you will need to block the
access to your data when you free it; it looks like one of your thread will try to access the data while your are free-ing it.
have a look at mutex, critical section, and all the other related mechanism for locking access to your data to only one thread.
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
I think I see what your saying, but the only thing that accesses the data after its created, is the same thread that free()'s it. So its not something else trying to access the data. Is that what you were getting at?
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
Jader89 wrote: newMsg->data = (char*)malloc( sizeof(msg.u.reqvid) );
Note the value of newMsg->data after this point.
Jader89 wrote: free(newMsg->data);
Note the value of newMsg->data before this point. Is it the same as it was after the call to malloc() ? If not, that's why free() is failing.
|
|
|
|
|
The pointer is a valid one, and the same as it is when its created.
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
Can you confirm that this works:
class GUIQueue
{
public:
char *data;
};
void main( void )
{
GUIQueue *newMsg = (GUIQueue *) malloc(sizeof(GUIQueue));
newMsg->data = (char *) malloc(15 * sizeof(char));
if (newMsg->data != NULL)
{
free(newMsg->data);
newMsg->data = NULL;
}
if (newMsg != NULL)
{
free(newMsg);
newMsg = NULL;
}
}
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
I'll try this out. As a side note, the free(newMsg) works fine... Its just the char* thats in the struct GUIQueue that doesnt seem to want to free... Ill reply soon on the results.
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
Yup, this segment of code works fine...
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
Then some other piece of code is changing newMsg->data before free() is called. Either take away from your current program, or add to this temporary program, until you find the offending statement(s).
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
Well it seems the mix up occurs somewhere between pushing the it on the queue, and taking it off. I tried just a push followed by a pop, and i run into the problem. Any ideas why?
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
Jader89 wrote: Any ideas why?
Not without seeing the code for the 'push' and 'pop' operations.
"Take only what you need and leave the land as you found it." - Native American Proverb
|
|
|
|
|
The queue:
std::queue<GUIQueue*> GUIQ;
the struct:
struct GUIQueue<br />
{<br />
bool isBmp;<br />
int size;<br />
char* data;<br />
};
other than that, i just imported the queue.h header file,
and used the methods push(), and front(), since pop doesnt really do anything
other than completely remove the front of the queue.
here is the failing code as one thread, also note, that without the push, and pop, the free()'s worked fine.:
GUIQueue* newMsg = (GUIQueue*)malloc( sizeof(GUIQueue) );<br />
memset( newMsg, 0, sizeof(GUIQueue) );<br />
newMsg->data = (char*)malloc( sizeof(msg.u.reqvid) );<br />
memcpy( newMsg->data, &msg, sizeof(msg.u.reqvid) + sizeof( MsgHeader ) );<br />
newMsg->size = sizeof(msg.u.reqvid) + sizeof(MsgHeader);<br />
newMsg->isBmp = true;<br />
GUIQ.push( newMsg );<br />
<br />
GUIQueue* test = (GUIQueue*)GUIQ.front();<br />
GUIQ.pop();<br />
if( test->data != NULL )<br />
{<br />
free(test->data);<br />
test->data = NULL;<br />
}<br />
if( test != NULL )<br />
{<br />
free(test);<br />
test = NULL;<br />
}
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
Correction:
If i keep the same pointer name, newMsg, and call free on that, it will work for both ->data, and on itself. But if i switch pointers names ,( i.e. GUIQueue* test = newMsg ), then call do the same free()'s but on test, it fails.
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
I figured out the problem, if you look back in my code, i malloc a certain amount, then do a memcpy that is bigger than that amount, causing it to do something bad... 8), easy error for alot work, lol.
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
DavidCrow wrote: newMsg->data = (char*)malloc( sizeof(msg.u.reqvid) );
should that be something like :
newMsg->data = (char*)malloc( msg.u.reqvid * sizeof(char ) );
Maximilien Lincourt
Your Head A Splode - Strong Bad
|
|
|
|
|
Its a typedef struct, im pretty sure this works, cuase it works in other parts of my code.
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|
I think this might be a hack, but im gonna create another GUIQ, with ready to be freed pointers, and when there used in my other thread, they get thrown away in this queue, which the other thread checks, and if there is anything in there, its free's it. Seems like a lot of work to free memory. Wonder why you it must be local heap to be able to free it.
"There are 10 types of people, those who understand binary, and those who don't."
- Somebody, not me.
|
|
|
|
|