Home > OS >  Returning a pointer to a static buffer
Returning a pointer to a static buffer

Time:07-02

In C on a small embedded system, is there any reason not to do this:

const char * filter_something(const char * original, const int max_length)
{
   static char buffer[BUFFER_SIZE];
  // checking inputs for safety omitted
  // copy input to buffer here with appropriate filtering etc
  return buffer;
}

this is essentially a utility function the source is FLASH memory which may be corrupted, we do a kind of "safe copy" to make sure we have a null terminated string. I chose to use a static buffer and make it available read only to the caller.

A colleague is telling me that I am somehow not respecting the scope of the buffer by doing this, to me it makes perfect sense for the use case we have.

I really do not see any reason not to do this. Can anyone give me one?

CodePudding user response:

It really depends on how filter_something is used. Take the following as an example

#include <stdio.h>
#include <string.h>

const char* filter(const char* original, const int max_length)
{
    static char buffer[1024];

    memset(buffer, 0, sizeof(buffer));
    memcpy(buffer, original, max_length);
    return buffer;
}

int main()
{
    printf("%s\n", filter("everybody", 10));
    printf("%s %s %s\n", filter("nobody", 7), filter("somebody", 9), filter("anybody", 8));

    if (strcmp(filter("same",5), filter("different", 10)) == 0)
        printf("Strings same\n");
    else
        printf("Strings different\n");
}

The output when gcc is used is

everybody
nobody nobody nobody
Strings same

When filter is used by itself, it behaves quite well. When it is used multiple times in an expression, the behaviour is undefined.

In C , this technique is often used when returning objects with the same consequences.

CodePudding user response:

Pro

  1. The behavior is well defined; the static buffer exists for the duration of the program and may be used by the program after filter_something returns.

Cons

  1. Returning a static buffer is prone to error because people writing calls to the routines may neglect or be unaware that a static buffer is returned. This can lead to attempts to use multiple instances of the buffer from multiple calls to the function (in the same thread or different threads). Clear documentation is essential.

  2. The static buffer exists for the duration of the program, so it occupies space at times when it may not be needed.

CodePudding user response:

It is true that the identifier buffer only has scope local to the block in which it is declared. However, because it is declared static, its lifetime is that of the full program.

So returning a pointer to a static variable is valid. In fact, many standard functions do this such as strtok and ctime.

The one thing you need to watch for is that such a function is not reentrant. For example, if you do something like this:

printf("filter 1: %s, filter 2: %s\n", 
       filter_something("abc", 3), filter_something("xyz", 3));

The two function calls can occur in any order, and both return the same pointer, so you'll get the same result printed twice (i.e. the result of whatever call happens to occur last) instead of two different results.

Also, if such a function is called from two different threads, you end up with a race condition with the threads reading/writing the same place.

  • Related