开发者

When is it safe to free a FP * in a Excel XLL?

开发者 https://www.devze.com 2023-04-12 11:55 出处:网络
MSDN states: ... Therefore, when returning a DLL-created string or floating-point array, you have the following choices:

MSDN states:

... Therefore, when returning a DLL-created string or floating-point array, you have the following choices:

  • Set a persistent pointer to a dynamically allocated buffer, return the pointer. On the next call to the function (1) check that the pointer is not null, (2) free the resources allocated on the previous call and reset the pointer to null, (3) reuse the pointer for a newly allocated block of memory. ...

I get the following error dialog when I call free:

MSVC++ Debug Library HEAP CORRUPTION DETECTED: after Normal block(#135) at 0x....... CRT detected that the application wrote to memory after end of healp buffer.

Here's my code:

FP * g_FP;

extern "C" FP * __stdcall xllFill(long rows, long cols) {

    if (g_FP != NULL) {
        free(g_FP);
        g_FP = NULL;
    }
    g_FP = (FP *)malloc(rows * cols * sizeof(double) + 2 * sizeof开发者_StackOverflow(unsigned short int));

    for (int i = 0; i < rows * cols; i++) {
        (*g_FP).data[i] = (double)i;
    }
    (*g_FP).rows = (unsigned short int)rows;
    (*g_FP).cols = (unsigned short int)cols;
    return g_FP;
}

I'm a bit rusty on C++ but I can't figure for the life of me why this isn't working.


FP is declared like this:

typedef struct _FP
{
    unsigned short int rows;
    unsigned short int columns;
    double array[1];        /* Actually, array[rows][columns] */
} FP;

You are assuming that FP is packed and contains no padding. I don't know how XLLs are meant to be compiled but I think it is very likely that there is padding between columns and array to arrange that array is 8 byte aligned. With default settings, MSVC returns 16 for sizeof(FP) which supports my hypothesis.

Change your allocation to this:

g_FP = malloc((rows*cols-1)*sizeof(double) + sizeof(*g_FP));

Even if this isn't the cause of your problem, the allocation above is the logically correct form.

Otherwise I cannot see anything wrong with your code. I think you could be more explicit in initialising g_FP to NULL but that's a minor point.


sizeof(FP) is 16, because rows and cols end up being aligned (presumably). I don't allow for this in my manual size calculation.

Better code would be:

g_FP = (FP *)malloc(sizeof(sizeof(FP) - sizeof(double) + rows * cols * sizeof(double)); // -sizeof(double) to account for the double[1] already in the struct def.


Save yourself some trouble and use the FP class from http://nxll.codeplex.com. The documentation for it is http://nxll.codeplex.com/wikipage?title=FP.

0

精彩评论

暂无评论...
验证码 换一张
取 消