Scott Allen Rauch
2010-05-29 21:49:01 UTC
Has anyone made a version of FreeXLOper12T that works?
FreeXLOper12T() is a great idea – one small routine to free all XLOPER12
data. However, I believe the code is faulty – i.e., there is no way it could
possibly work.
Presumably, this function would be called by xlAutoFree12() the entire guts
of which would be (assuming we are using the TLS API),
void WINAPI xlAutoFree12( LPXLOPER12 pxFree )
{
FreeXLOper12T( pxFree ) ; // Free all memory
// DO NOT free pxFree! It is freed by TLS_Action() when called by DllMain()
}
However, the first few lines of FreeXLOper12T() are,
void FreeXLOper12T(LPXLOPER12 pxloper12)
{
DWORD xltype;
int cxloper12;
LPXLOPER12 pxloper12Free;
xltype = pxloper12->xltype;
switch (xltype)
{
case xltypeStr:
According to the XL SDK, the pxloper12->xltype will still have xlbitDLLFree
set. Thus, there can never be a match, and the function does nothing. I have
verified this by creating an xltypeMulti with 1,000,000 XLOPER12s (that each
contain statex.dwMemoryLoad), and watching the memory usage increase with
every recalculation.
So, I changed one line of FreeXLOper12T( ) to strip off the xlbitDLLFree.
The first few lines now look like this:
void FreeXLOper12T( LPXLOPER12 pxloper12 )
{
DWORD xltype;
int cxloper12;
LPXLOPER12 pxloper12Free;
xltype = pxloper12->xltype & 0x0FFF; // Strip off xlbitDLLFree
switch (xltype)
{
case xltypeStr :
Now this switch statement works.
I have verified this because now Excel crashes when given an xltypeMulti!
Here is the case xltypeMulti code snippet:
case xltypeMulti:
cxloper12 = pxloper12->val.array.rows * pxloper12->val.array.columns;
if (pxloper12->val.array.lparray)
{
pxloper12Free = pxloper12->val.array.lparray;
while (cxloper12 > 0)
{
FreeXLOper12T(pxloper12Free);
pxloper12Free++;
cxloper12--;
}
free(pxloper12->val.array.lparray);
}
break;
The offending line is the recursive call,
FreeXLOper12T(pxloper12Free);
Comment out that line, and Excel does not crash. However, that is the magic
line in the routine, Without that line, it never frees pointed-to memory
(i.e., when pxloper12Free contains xltypeStr, xltypeRef, xltypeMulti, or
xltypeBigData.) I cannot figure out why that causes a crash. It looks like
good code to me!
So, my question is, has anyone made a version of FreeXLOper12T that works?
FreeXLOper12T() is a great idea – one small routine to free all XLOPER12
data. However, I believe the code is faulty – i.e., there is no way it could
possibly work.
Presumably, this function would be called by xlAutoFree12() the entire guts
of which would be (assuming we are using the TLS API),
void WINAPI xlAutoFree12( LPXLOPER12 pxFree )
{
FreeXLOper12T( pxFree ) ; // Free all memory
// DO NOT free pxFree! It is freed by TLS_Action() when called by DllMain()
}
However, the first few lines of FreeXLOper12T() are,
void FreeXLOper12T(LPXLOPER12 pxloper12)
{
DWORD xltype;
int cxloper12;
LPXLOPER12 pxloper12Free;
xltype = pxloper12->xltype;
switch (xltype)
{
case xltypeStr:
According to the XL SDK, the pxloper12->xltype will still have xlbitDLLFree
set. Thus, there can never be a match, and the function does nothing. I have
verified this by creating an xltypeMulti with 1,000,000 XLOPER12s (that each
contain statex.dwMemoryLoad), and watching the memory usage increase with
every recalculation.
So, I changed one line of FreeXLOper12T( ) to strip off the xlbitDLLFree.
The first few lines now look like this:
void FreeXLOper12T( LPXLOPER12 pxloper12 )
{
DWORD xltype;
int cxloper12;
LPXLOPER12 pxloper12Free;
xltype = pxloper12->xltype & 0x0FFF; // Strip off xlbitDLLFree
switch (xltype)
{
case xltypeStr :
Now this switch statement works.
I have verified this because now Excel crashes when given an xltypeMulti!
Here is the case xltypeMulti code snippet:
case xltypeMulti:
cxloper12 = pxloper12->val.array.rows * pxloper12->val.array.columns;
if (pxloper12->val.array.lparray)
{
pxloper12Free = pxloper12->val.array.lparray;
while (cxloper12 > 0)
{
FreeXLOper12T(pxloper12Free);
pxloper12Free++;
cxloper12--;
}
free(pxloper12->val.array.lparray);
}
break;
The offending line is the recursive call,
FreeXLOper12T(pxloper12Free);
Comment out that line, and Excel does not crash. However, that is the magic
line in the routine, Without that line, it never frees pointed-to memory
(i.e., when pxloper12Free contains xltypeStr, xltypeRef, xltypeMulti, or
xltypeBigData.) I cannot figure out why that causes a crash. It looks like
good code to me!
So, my question is, has anyone made a version of FreeXLOper12T that works?