什么时候在 Excel XLL 中释放 FP * 是安全的?

发布于 2024-12-08 21:54:38 字数 967 浏览 3 评论 0原文

MSDN 声明

...因此,当返回 DLL 创建的字符串或浮点数时 数组,您有以下选择:

  • 设置一个指向动态分配缓冲区的持久指针,返回该指针。在下次调用函数 (1) 时,检查 指针不为空,(2)释放之前分配的资源 调用并将指针重置为空,(3)将指针重新用于新的 分配的内存块。 ...

当我调用 free 时,出现以下错误对话框:

MSVC++ 调试库检测到堆损坏:正常后 block(#135) at 0x....... CRT 检测到应用程序写入 修复缓冲区结束后的内存。

这是我的代码:

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++ 有点生疏,但我无法弄清楚为什么这不起作用。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

仙女山的月亮 2024-12-15 21:54:38

FP 的声明如下:

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

您假设 FP 已打包并且不包含任何填充。我不知道 XLL 是如何编译的,但我认为很可能在 columnsarray 之间有填充来排列该 array 是 8 字节对齐的。使用默认设置,MSVC 对于 sizeof(FP) 返回 16,这支持了我的假设。

将您的分配更改为:

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

即使这不是问题的原因,上面的分配也是逻辑上正确的形式。

否则我看不出你的代码有什么问题。我认为您可以更明确地将 g_FP 初始化为 NULL 但这是一个小问题。

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.

二智少女 2024-12-15 21:54:38

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.

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.
拔了角的鹿 2024-12-15 21:54:38

为自己省去一些麻烦,请使用 http://nxll.codeplex.com 中的 FP 类。它的文档是 http://nxll.codeplex.com/wikipage?title=FP

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文