Когда безопасно освободить FP * в Excel XLL? - PullRequest
2 голосов
/ 10 октября 2011

Состояния MSDN :

... Поэтому при возврате созданной DLL строки или массива с плавающей запятой у вас есть следующие варианты:

  • Установить постоянный указатель на динамически выделенный буфер, вернуть указатель.При следующем вызове функции (1) проверьте, что указатель не равен нулю, (2) освободите ресурсы, выделенные при предыдущем вызове, и сбросьте указатель до нуля, (3) повторно используйте указатель для вновь выделенного блока памяти....

При вызове free я получаю следующее диалоговое окно с сообщением об ошибке:

MSVC ++ Библиотека отладки ОБНАРУЖЕНА КОРРУПЦИЯ КАРТЫ: после блока Normal (# 135)0x ....... CRT обнаружил, что приложение записало в память после завершения буфера healp.

Вот мой код:

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;
}

Я немного ржавыйна C ++, но я не могу понять, почему это не работает.

Ответы [ 3 ]

2 голосов
/ 10 октября 2011

FP объявляется так:

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

Вы предполагаете, что FP упакован и не содержит отступов.Я не знаю, как XLL-файлы предназначены для компиляции, но я думаю, что вполне вероятно, что между columns и array есть заполнение для того, чтобы array было выровнено на 8 байт.При настройках по умолчанию MSVC возвращает 16 для sizeof(FP), что поддерживает мою гипотезу.

Измените ваше распределение на:

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

Даже если это не является причиной вашей проблемы,Вышеприведенное распределение является логически правильной формой.

В противном случае я не вижу ничего плохого в вашем коде.Я думаю, что вы могли бы быть более явным при инициализации g_FP до NULL, но это второстепенный момент.

1 голос
/ 10 октября 2011

sizeof(FP) равно 16, потому что строки и столбцы в конечном итоге выровнены (предположительно).Я не допускаю этого в моем ручном расчете размера.

Лучший код будет:

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.
0 голосов
/ 05 ноября 2011

Избавьте себя от неприятностей и используйте класс FP из http://nxll.codeplex.com. Документация для него: http://nxll.codeplex.com/wikipage?title=FP.

...