3

我必须在 C 中编写一个 DLL,其中包含一个返回特定字符串的函数(作为指向表示字符串的 char 缓冲区的指针)。DLL 中的函数将被重复调用,并在不同的线程中执行。

正确的做法是在函数中分配 char 缓冲区,并在使用返回缓冲区后在调用者环境中释放分配的缓冲区。

// DLL function

char *getString() {
    char *buffer = (char *)malloc(STRING_LEN);
    // fill buffer with some string
    return buffer;
}

不幸的是,将在我的 dll 中调用该函数的编程环境没有释放返回缓冲区的机制,因此导致内存泄漏。

如何在这种情况下返回字符串而不产生内存泄漏?

4

2 回答 2

3

DLL 使用单独的堆,因此在 dll 中分配的内容必须由同一个 dll 释放。

正如 hmjd 所说,一种选择是将缓冲区返回给将它提供给您的 DLL,以便它删除它。所以dll提供了一个释放功能。

我更喜欢的另一个选择是让调用程序自己提供内存。例如,您在调用程序中分配缓冲区并将其传入,包括缓冲区的长度,如果缓冲区不够大,则 dll 函数以所需的长度失败。像这样:

bool doStuff( char* buffer, int& len )
{
    if ( len < tooSmall() )
    {
       len = requiredLength();
       return false;
    }

    // fill the buffer here somehow

    return true;
}

然后您可以照常管理调用程序中的缓冲区。这样做的一个优点是调用程序很容易在有意义的情况下重用缓冲区。

于 2012-10-22T21:03:23.000 回答
2

是否可以修改 API 以便调用者提供缓冲区?maxStringLength为(或标题或函数中的宏)添加一个常量,以便调用者始终可以为返回字符串分配足够的空间。

// DLL
const size_t maxStringLength = STRING_LEN;
char *getString( char *buffer, size_t buffer_size) {
    // fill buffer with some string
    return buffer;
}

// calling code
char *my_buffer = malloc( maxStringLength);
if (my_buffer != NULL)
{
    getString( my_buffer, maxStringLength);
    // use string
    free( my_buffer);
}
于 2012-10-22T21:02:53.260 回答