简体   繁体   中英

Is it good practice to return static arrays in C to avoid memory leaks?

I'm having some doubts regarding the use of static arrays as a return value in functions to avoid a rather complex use of free() .

I'm in charge of solving some memory leaks inside a C program. These leaks are happening when calling a macro directly as a function parameter:

snprintf( ..., MACRO, ...);

When some conditions are met, this macro calls a function that uses malloc() to allocate memory:

#define MACRO ({ \
    char * problematicVariable = ... ? problematicFunction(NULL) : fixedValue; \
    // Some if statements... 
    problematicVariable; \
})

The way both promlematicFunction() and MACRO are implemented in the program makes it impossible to correctly free the memory unless doing heavy changes, so a workaround I've happen to find is to free the memory directly inside the problematicFunction() , after copying its value in a static array:

char *problematicFunction(char *arg) 
{
    char *buff = malloc(PATH_MAX);
    static char temp[PATH_MAX];

    // Doing stuff with buff...

    if (strlcpy(temp, buff, sizeof(temp)) >= sizeof(temp))
    {
        // Handle error...
    }

    free(buff);
    return(temp);
}

Can something like this be considered good practice? The return value is supposed to be read-only.

Thanks in advance!

This depends on context. In most hosted systems, using internal variables with static storage duration, or returning pointers to them, is frowned upon. Because that makes the functions unsuitable for multi-threading - they are not thread-safe unless you explicitly add mutex or similar mechanisms. And writing the function re-entrant , with caller allocation and no global resources etc is considered best practice when possible.

And of course, if the function doesn't reset the static storage resource, it can only be called once. This makes sense for a "singleton" design pattern, but not for a general library.

In freestanding (embedded etc) systems however, you often work with static memory pools, since such systems are often single-thread and also ban the use of heap allocation.

Generally, code using malloc is properly written if the code module that did the malloc is also the one responsible for cleaning up its own mess , by providing a function for that, which is a wrapper around all necessary free() calls. For every malloc call there should be a corresponding free call, in the same code. This goes for all manner of other dynamic resource too, file handles, threads etc.

The past ~40 years of C programming history shows that memory leaks most often appear when you come up with dysfunctional library APIs (like for example POSIX getline ), where the caller is made responsible to manually clean up something allocated by the library. If the library instead uses proper design with private encapsulation, memory leaks shouldn't happen.

Now of course C doesn't have RAII or destructors, so instead C programmers using a library must be trusted to activate their brain and call a function foo_cleanup() if the "foo library" provides that one and tells the programmer to call it when they are done using the resource.

Returning static buffer is OK, but only in single-threaded environment. Many functions in standard C library are implemented this way (for example strerror function). If you want to make them thread-safe, you must pass buffer as a parameter to the function (strerror_r). In this case it is up to the caller if he allocates buffer in static, dynamic memory or on the stack (this one is really flexible, but beware of stackoverflow on embedded systems:)).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM