Question

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(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.

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top