 |
|
 |
Thanks.
It's very helpful to me.
|
|
|
|
 |
|
 |
Although this is an older post, I found it to be a big help, thank you for this very useful topic..
-O-
http://paradisim.zxq.net
modified 7 Nov '11.
|
|
|
|
 |
|
 |
Interesting demonstration of a weakness of afxteml. Not that I dislike it. Just that I spend enough time with my own bugs! I expect a "tools" to work.
|
|
|
|
 |
|
|
 |
|
 |
i always get error when i compile it
|
|
|
|
 |
|
 |
In my project, I used the CArray to save a struct , because I used a DLL to deal with the database , I only call api from dll to deal with the database,
the api will return the result ,and write into array! as I exit my application,it reports free array element error!so I debug to the follow function:
_CRTIMP int __cdecl _CrtIsValidHeapPointer(
const void * pUserData
)
{
#ifndef WINHEAP
int i;
void * base;
#endif /* WINHEAP */
if (!pUserData)
return FALSE;
if (!_CrtIsValidPointer(pHdr(pUserData), sizeof(_CrtMemBlockHeader), TRUE))
return FALSE;
#ifdef WINHEAP
if ( __active_heap == __V6_HEAP )
{
PHEADER pHeader;
if (pHeader = __sbh_find_block(pHdr(pUserData)))
{
return __sbh_verify_block(pHeader, pHdr(pUserData));
}
else if ( (_osver & 0x8000) != 0 )
return TRUE;
else
return HeapValidate( _crtheap, 0, pHdr(pUserData) );
}
else if ( __active_heap == __V5_HEAP )
{
__old_sbh_region_t * preg;
__old_sbh_page_t * ppage;
__old_page_map_t * pmap;
if ( (pmap = __old_sbh_find_block( pHdr(pUserData), &preg, &ppage )) !=
NULL )
{
if ( *pmap )
return TRUE;
else
return FALSE;
}
else if ( (_osver & 0x8000) != 0 )
return TRUE;
else
return HeapValidate( _crtheap, 0, pHdr(pUserData) );
}
else // __active_heap == _SYSTEM_HEAP
return HeapValidate( _crtheap, 0, pHdr(pUserData) );
#else /* WINHEAP */
/*
* Go through the heap regions and see if the pointer lies within one
* of the regions of the local heap.
*
* Pointers from non-local heaps cannot be handled. For example, a
* non-local pointer may come from a DLL that has the CRT linked-in.
*
*/
#ifdef _WIN32
for (i = 0; (base = _heap_regions[i]._regbase) != NULL &&
i < _HEAP_REGIONMAX; i++)
{
if (pUserData >= base && pUserData <
(void *)(((char *)base)+_heap_regions[i]._currsize))
return TRUE;
}
#else /* _WIN32 */
{
struct _heap_region_ *pHeapRegions
= (struct _heap_region_ *)(*hHeapRegions);
for (i = 0; (base = (pHeapRegions+i)->_regbase) != NULL &&
i < _HEAP_REGIONMAX; i++)
{
if (pUserData >= base && pUserData <
(void *)(((char *)base)+(pHeapRegions+i)->_currsize))
return TRUE;
}
}
#endif /* _WIN32 */
return FALSE;
#endif /* WINHEAP */
}
then report error! I do not know how to deal with it!
|
|
|
|
 |
|
 |
Without seeing for myself, I can't say for sure, but I don't think this problem is caused by CArray. If I had to guess, since it's during "exit time", I would say that you're trying to use a pointer that is no longer valid.
Best of luck sorting this one out...
Warren
|
|
|
|
 |
|
 |
The thing to do with the CArray was not possible in my code..
i think i sent the snippet to ur mail for the clarification...
i'll add it here too..
void CTrytestDlg::OnOK()
{
CArray hi;
hi.Add(10);
hi.Add(20);
int m=1;
hi.InsertAt(m,233 );
char a[10];
sprintf(a,"%d",hi[1]);
AfxMessageBox(a);
fun(hi);
CDialog::OnOK();
}
void CTrytestDlg::fun(CArray& hi)
{
AfxMessageBox("sanhtosh");
}
please give reply
|
|
|
|
 |
|
 |
bagchisandeep wrote: CArray hi;
Yes, it will work (I replied to your email too). What is missing is filling in the template parameters (CArray instead of just CArray)
Also, consider using the STL vector class instead of CArray, if this is available in your compiler/IDE. (see other comments below, and the MSDN docs)
Warren
|
|
|
|
 |
|
 |
hi everyone i'm new to VC++ and MFC's,
Is it possible to return the CArray object?
how i can pass the CArray object to a function.
if,
.
.
CArray arr;
arr.Add(10);
arr.Add(23);
function(arr);
..
function(CArray arr1)
{
//some Manupulation using array.
}
|
|
|
|
 |
|
 |
You should pass it as a "reference" instead of as a "value".
Instead of:
bagchisandeep wrote: function(CArray arr1)
{
//some Manupulation using array.
}
just add a "&" behind the type:
bagchisandeep wrote: function(CArray& arr1)
{
//some Manupulation using array.
}
i.e. it's exactly the same as before just with "CArray&" instead of "CArray". When you do this:
1) can modify the item within the function
2) the item doesn't get copied (it's refrenced), so it's efficient.
Note: This applies to all C++ objects, not just MFC arrays.
Warren
|
|
|
|
 |
|
 |
I'd like to add a comment here, with regards to making a choice between CArray and std::vector...
Please keep in mind that the article is over 5 years old while I write this comment.
Nowadays I use the STL std::vector class exclusively and haven't used CArray for any new code in about a year (or so). Unless you've got a really good reason not to, I'd suggest using std::vector in ALL cases, and drop CArray (once you've used the STL sorting and std::pair, you'll never look back)
If you're stuck with Visual C++ 6.0, I'd seriously suggest upgrading when Visual Studio 2005 comes out in a month or so. Except for the classwizard (which was handy), you won't miss anything.
Having said that, I'd have to say I'm disappointed Microsoft didn't fix the CArray class (or at least add an ASSERT if the newElement memory location is in the existing array when SetSize is called), considering how many versions of Visual Studio have come out in the past 5 years. I have little doubt that there are subtle bugs still sitting out there in many a program...
Warren
|
|
|
|
 |
|
 |
If you wanted to correct the class, could you do somthing like this?:
template< class TYPE, class ARG_TYPE>
void CArray< TYPE, ARG_TYPE>::SetAtGrow(int nIndex, ARG_TYPE newElement)
{
ASSERT_VALID(this);
ASSERT(nIndex >= 0);
TYPE *cpyElement = NULL;
if (&newElement>=m_pData && &newElement<m_pData+m_nSize)
{
cpyElement = new TYPE;
*cpyElement = newElement;
}
if (nIndex >= m_nSize)
SetSize(nIndex+1, -1);
m_pData[nIndex] = cpyElement ? *cpyElement : newElement;
}
Something similar should be done in the code of InsertAt... what do you think about this???
|
|
|
|
 |
|
 |
Yes, you could do something like that, but that requires an extra "new" (in the handling of the special case).
How I would fix it, would be to write a private function called SetSizeNoDelete which is the same as the existing SetSize
except:
1) with the following line removed:
delete[] (BYTE*)m_pData;
2) the return value would be the old data pointer
Then we would change the SetAtGrow function to:
if (nIndex >= m_nSize) {
BYTE* pOldData = SetSizeNoDelete(nIndex+1, -1);
m_pData[nIndex] = newElement;
delete[] (BYTE*)pOldData;
}else{
m_pData[nIndex] = newElement;
}
This fixes the problem, and doesn't have any extra memory allocations
|
|
|
|
 |
|
 |
i want to know how to pass CArray object to function and return the CArray
object from function...
Thanks
-Renugopal
|
|
|
|
 |
|
 |
pass it to the funtion as a reference. Using a typedef will make it cleaner. For example: typedef CArray < int,int& > IntArray; void SomeFunction() { IntArray array; array.Add(2); array.Add(4); OtherFunction(arrayToEdit); // size should be 3 here } void OtherFunction(IntArray& arrayToEdit) { arrayToEdit.Add(4); }
|
|
|
|
 |
|
 |
Hi there,
Could you please tell me how to use CRgn in CArray..
I cant Add elements to It, It shows error,
'Cannot convert from CRgn to CRgn'..
I noticed that the CRgn Dont have a Copy Constructor and doesn't have an overloaded operator '='
Can u discribe it with an example...if possible
Thanks In Advance
Regards,
Rajesh
|
|
|
|
 |
|
 |
Have you tried writing:
CArray
instead of:
CArray
that might work? (I haven't tried it, since I don't have developer studio in front of me, I'm just guessing here). A lot of classes don't have an explicit copy constructor or operator= written for them because the compiler can often write the correct one automatically.
If that doesn't work, you can always write it like:
CArray some_name
to store an array of pointers. This WILL work.
and then just use:
some_name.Add(new CRgn());
to add to it (and don't forget to go through your array and delete your pointers when you're done with them).
Warren
|
|
|
|
 |
|
 |
I just tried it out, now that I have access to developer studio.
As you were suggesting, the problem is with the lack of a operator= which isn't available for CRgn objects (because they are more complicated than just C++ objects, they wrap Windows resources so copying is not a trivial exercise).
You can always write it like:
CArray < CRgn* , CRgn* > array_name
to store an array of pointers. This WILL work.
and then just use:
some_name.Add(new CRgn());
to add to it (and don't forget to go through your array and delete your pointers when you're done with them).
Warren
|
|
|
|
 |
|
 |
Do you know if the size in Carray is limited or unlimited? Thanks a lot.
|
|
|
|
 |
|
 |
I'd say it's "unlimited", as there isn't an actual hardcoded limit to the size.
Of course, you can run out of memory and a memory allocation will fail, but similar things will happen with any type of similar dynamic-sized array class (e.g. STL vector, new malloc, etc).
Warren
|
|
|
|
 |
|
 |
hi!
i dont seem to know whats was the problem with my code while using CArray
i had to store structures in it. when i used the CArray::Add(), it didnt add anything and no error code was generated.
finally i counted on my own skills n wrote my own code to add n access the array elements n saying goodbye to "CArray"....
the code is listed ...please if u could solve the problem n return me to my lost love(CArray i.e.)
heres the code
declaration:
CArray m_list;
"where GUI is a structure"
struct GUI {
//Parent Information
HWND HParent;
TCHAR PLabel[100];
TCHAR PMSW_Class[100];
LONG PMSW_ID;
//Currnet Information
UINT message;
HWND Handle;
TCHAR Label[100];
TCHAR MSW_Class[100];
LONG Width;
LONG Height;
LONG MSW_ID;
LONG Abs_x;
LONG Abs_y;
LONG rel_x;
LONG rel_y;
DWORD dwStyle;
DWORD dwExStyle;
} ;
//.........inside the code..............
GUI local_info;//local variable in a callback function
//i fill this local_info in my code n try to add using...
m_list.Add(local_info);//this doesnt add anything in the array
*************************
this local_info gives accurate results when i filled my own array....
but i dint seem to know what was the problem with my code....
regards
Owais
|
|
|
|
 |
|
 |
Owais,
Typically the declaration for a CArray has the class name as the first parameter to the template, and a reference to the class as the second parameter to the template.
ie. CArray m_list;
Since you're going down the MFC path (by using CArray), you might want to change your
TCHAR some_variable_name[100];
to
CString some_variable_name;
(why worry about 1) NULL terminating your strings and 2) dealing with the possibility
of >100 character length strings, if you don't have to?)
Warren
|
|
|
|
 |
|
 |
such code
CArray > DoubleArray;
can't compiled in VC6. But int std::vector it work well.
Sclzmbie.San
|
|
|
|
 |
|
 |
fix HTML bug, above code is: CArray<CArray<int, int> > DoubleArray; . Sclzmbie.San
|
|
|
|
 |