Link to home
Start Free TrialLog in
Avatar of MCofer
MCofer

asked on

How to free memory using a COleSafeArray

I am creating and loading a COleSafeArray form Excel

COleSafeArray saRet;
CRange oRange = oSheet.get_Range(COleVariant(csStart),COleVariant(csEnd));
saRet = oRange.get_Value(vOpt);


Everytime  I run my code the windows memory usage increases; + 30meg;
I found Q_20742007.html  but the answer does not work for me;
SetProcessWorkingSetSize(GetCurrentProcess(), 0xFFFFFFFF, 0xFFFFFFFF);
maybe because my code is a DLL addin to another application.

My Code is almost a copy of MSDN example http://support.microsoft.com/kb/308407/EN-US/#2


I have tried       saRet->DestroyData();
            saRet.Destroy();
            saRet->Clear();
Nothing Helps
What to try next?

Avatar of danielsonchris
danielsonchris

Have you checked your Lock count on this particular item?  Perhaps the item has been locked and not unlocked the same number of times.  In the COM world... An array cannot be deleted while it is locked.  Or if the lock count has been incremented without sufficient Unlock(...) calls.

check here:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/automat/htm/chap7_66jv.asp
--or--
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_colesafearray.3a3a.unlock.asp

On another note the memory usage does seem a bit large, BUT I must say I have seen this issue whenever I incorporate the Office COM libraries which is what you are doing in this particular instance.  

In the particular scenario you showed from the MS site, you would not need to reclaim the SafeArray, but you would want to make sure that you did not leave a positive lock count on the item.  Just be careful about releasing the Excel COM object when your program exits.  Otherwise you'll leave 'em in memory which is pretty ugly.

Regards,
Chris
Avatar of MCofer

ASKER

I'm using
long nIndex[2];
COleVariant vData;
for (int nRow = 0; nRow < nRows; nRow++)
{
    for (int nCol = 0; nCol < nCols; nCol++)
    {
       nIndex[0] = nRow+1;
       nIndex[1] = nCol+1;
       saRet.GetElement(nIndex,vData);
to acces the data according to :
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vclib/html/_mfc_colesafearray.3a3a.accessdata.asp
Lock and Unlock are called automaticly;

trying to use either
saRet.UnaccessData();
or
saRet.Unlock();
returns an exception error.
In the scenario listed above, you would not need to call an Unaccessdata().  You would only need to do that if you were calling AccessData().  Basically, leave the COLEsafearray vaiable as is.  The lock count is reset for sure if you are only using GetElement(..)
You would only need to manually aid the variable if you were doing anything that could increment the locks and unlocks.

Regards,
Chris
Avatar of MCofer

ASKER

If I simply run
 COleSafeArray saRet;
CRange oRange = oSheet.get_Range(COleVariant(csStart),COleVariant(csEnd));
saRet = oRange.get_Value(vOpt);
and exit (never try to access the data) the memory is not released.
the problem occurs when the COleSafeArray is loaded and is not released when the array goes out of scope
I tried using new/delete and got the same results
I can use
COleVariant vData = oRange.get_Value(vOpt);
instead of using the COleSafeArray  but looping through the entire excel sheet is very slow compared to loading the array
this is a critical problem for me so I am increassing the points to 500
Please continue helping.

Thanks
ASKER CERTIFIED SOLUTION
Avatar of danielsonchris
danielsonchris

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of MCofer

ASKER

I've been a week or so geting back.
I had to get my application working without using COleSafeArray
The  detach/VariantClear looks like it should work but from the examples I do not understand how to use it.
 COleSafeArray saRet;
saRet = oRange.get_Value(vOpt);  Gets the objects in an excel range inn my case 200 columns
                                                   by 1000 rows (uses about 10 meg of memory.
Now to detach a variant array
VARIANT vData = saRet.Detach(); only returns one variant value. how doi i get and clear the
                                                  entire array??


Avatar of MCofer

ASKER

All of the answers were informative but nothing solved the memory problem
Does anyone have any other Ideas or should I close the question?
Avatar of MCofer

ASKER

None of the suggestions really worked but the Info was helpful
Thanks for the effort