|
Michel Prévost wrote:
I followed Rama's instructions and I found it.
But it does not exist in my computer.I don't think its thr part of default installation in VS.Net.
|
|
|
|
|
If I am using some code as follows
aThreads[iArrayIndex] = AfxBeginThread(ClientExtractThread, (LPARAM)pExtractor);
...
...
iArrayIndex = WaitForMultipleObjects(MAX_CONCURRENT_THREADS,aThreads,FALSE,INFINITE);
...
...
GetExitCodeThread(aThreads[iArrayIndex]->m_hHandle, &nRetVal);
I'm concerned that the member variable m_bAutoDelete of the CWinThread object created by AfxBeginThread, which defaults to TRUE, will cause the GetExitCodeThread call to not function correctly. Alternatively I can set this member to FALSE, but then I don't know what I have to clean up? Should I just call delete after the GetExitCodeThread has finished.
delete (CWinThread*)aThreads[iArrayIndex];
Thanks for any suggestions.
Chris
|
|
|
|
|
As you have said you can delete the CWinThread object safely
after you have got the Exit Code.
|
|
|
|
|
|
If you set m_bAutoDelete to TRUE, your thread will delete yourself. The value of 'aThreads[iArrayIndex]' in GetExitCodeThread call points to freed memory block and there's absolutely no guarantee that m_Handle contains valid value.
In short, you shouldn't use m_bAutoDelete --or-- you should store thread handles in other location.
Tomasz Sowinski -- http://www.shooltz.com
- It's for protection - Protection from what? Zee Germans?
|
|
|
|
|
Thanks Tomasz. You always have some good insight to offer.
I do end up having to store the thread handles in an other array since I need to pass an array of thread handles to the WaitForMultipleObjects call that I make.
Additionally, I am going to use m_bAutoDelete. But I'm going to set it to FALSE, so that when the thread completes, I can call still call GetExitCodeThread and the thread handle should still be valid. After getting the exit code value, I will then 'delete' the thread.
Thanks for the comment.
Chris
|
|
|
|
|
I have code that looks like:
CArray<obj *,="" obj="" *=""> ArrayOfObjPtrs;
ObjPtr op=new Obj();
ArrayOfObjPtrs.Add(op);
Then in another function called later in the same thread, I do:
delete ArrayOfObjPtrs.GetAt(0); // free the object ** run-time error on this line **
ArrayOfObjPtrs.RemoveAt(0);
the Run-time error is in MSVCRTD, but the last call of mine is on the stack right before it, is "Obj::`scalar deleting desctructor' (unsigned int 1) + 56 bytes
I get a Debug Asseertion:
dbgdel.cpp Line 47, Expression _BLOCK_TYPE_IS_VALID(pHead->nBlockUse)
Can anyone please tell me what is going on? Thanks soooo much!
PS. Commenting out the 'delete' line results in a memory leak
|
|
|
|
|
Probabaly you could remove the element first and then delete it next using an
intermediatery temp variable.
|
|
|
|
|
What effect would that have?
|
|
|
|
|
How does the class ObjPtr look? Looks to me that there is some sort of a casting problem.
I feel that ArrayOfObjPtrs.GetAt(0) is not returning Obj* for some reason.
|
|
|
|
|
new() returns a pointer This pointer to the object, not the object itself, is stored in the CArray
|
|
|
|
|
What is ObjPtr is it a class or there was a typo in the original mail
ObjPtr op = new Obj();
or is it
Obj* op = new Obj();
How does you ObjPtr class look?
|
|
|
|
|
Im my example, they both are the same. ObjPtr is a Obj *
Sorry for the abiguity.
|
|
|
|
|
Try telling the CArray what kind of thing you will be storing in it. For example if you were storing pointers to CString objects, you would define it like this:
CArray<cstring *,="" cstring="" *=""> myArray;
|
|
|
|
|
i usually get this error when trying to delete a ptr to an object allocated on the stack. you'll have to check your code (esp. typedef's in yout case: ?ObjPtr?)
HTH,
|
|
|
|
|
Hope u're not doing something like: delete this; within the destructor. It may have destroyed the pointer when u exited the function within which u did the allocation. That's a rather strange characteristic of C++. If that's not the case then u may have destroyed the object somewhere else without realizing it,otherwise there's no reason the above code should throw that exception.
|
|
|
|
|
IN VC++ 6. how do you 'Watch' an entire array - Not just the individual elements.
|
|
|
|
|
1. Watch in the memory window
2. List all individual elements in the watch window
|
|
|
|
|
If you open up the watch window, you can type in the name of the array. Then you will be able to click on the plus button to the left of the array and expand all of its elements.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
The array was allocated dynamically...wud that be the reason why, when I click the + sign, it shows only the first element and not all of them ?
|
|
|
|
|
Yes, that would be the problem. The debugger is not quite sure how long your buffer is. In that case you can qualify your data by placing a comma (,) after the name of your pointer, and the number of elements that you want to watch.
Build a man a fire, and he will be warm for a day Light a man on fire, and he will be warm for the rest of his life!
|
|
|
|
|
yeah, use format specifiers. e.g.
"20x" will show 20 elements in hex
"20d" will show 20 elements in decimal
"20m" will dump 20 bytes of memory
experiment!
also check "r" for structs
HTH,
|
|
|
|
|
For a dynamically allocated array, you can put in
Pointer_name,#
Where # is the number of elements you want to watch.
Roger Allen
Sonork 100.10016
If I had a quote, it would be a very good one.
|
|
|
|
|
I have a CObject based class which supports serialization, but am having problems with classes derived from that.
Basically I have the main object which contains all the data, and a serialization function that works fine for that object, and a set of various classes that are all derived from that base class, which provide slightly different functionality, but all work off the data members in the base class.
The data structure builds up as a tree of objects (each object has a pointer to the next item in the list, and also a child)
Now the problem is that these children are all of different types (but all derived from the original base class).
I serialize the code like this
rxArchive >> m_pxNextEvent;
rxArchive >> m_pxFirstSubEvent;
(same for saving but with <<s)
each derived="" class="" has="" its="" own="" serialize="" function="" which="" simply="" calls="" the="" main="" class's="" serialize.
when="" i="" store="" data,="" correct="" functions="" get="" called,="" but="" when="" loading="" back="" in="" only="" base="" seems="" to="" used,="" and="" an="" error="" message="" saying="" "<filename>="" contained="" invalid="" object"
any="" ideas?=""
--
help="" me!="" i'm="" turning="" into="" a="" <a="" href="http://www.grapefruitopia.com">grapefruit!
|
|
|
|
|
No stead fast solution for this, because you dont know
what object's data you are going to read next and the object
might not exist in the program till then and has to be created.
What i would do is read in thru the base and then check for the
type of object based on the information just read in and then
create the derived class object.
You could have a member which would store a code which signifies
which class type does it belongs to!
|
|
|
|