Returning a Non-Static String

It’s possible to return a string created in a function without declaring it static. This trick requires some understanding of how functions return values. Nerd alert!

Functions in C return only single values. If you want to return multiple values, you can pack them into a structure or you can pass pointers as arguments. To return an array declared in a function, such as a char array or string, you must assign its value as static. Otherwise, like all variables used in a function, its value is discarded when the function ends.

Internally (and forgive my inner nerd for a paragraph), functions return single values by pushing them onto the stack. Only one value is pushed, which can be an int, float, char, struct, or an address (pointer). None of these items need be declared static within the function as the value is pushed onto the stack. The storage allocated for the variable is lost when the function exits.

The following code shows my binString() function, which accepts an 8-bit value and returns it as an 8-character string represent a binary number. The bin[] array is declared static at Line 6.

2022_07_23-Lesson-a.c

#include <stdio.h>

char *binString(unsigned char n)
{
    const int width = 8;        /* dealing the 8-bit bytes */
    static char bin[width+1];    /* +1 for the null char */
    int x;

    /* test each bit and set a character for its value */
    for(x=0;x<width;x++)
    {
        bin[x] = n & 0x80 ? '1' : '0';
        n <<= 1;
    }
    bin[width] = '\0';        /* cap the string */

    return(bin);
}

int main()
{
    int value;

    printf("Enter an integer value, 0 to 255: ");
    scanf("%d",&value);
    printf("Binary value is %s\n",binString((unsigned char)value));

    return(0);
}

Here’s a sample run:

Enter an integer value, 0 to 255: 237
Binary value is 11101101

If I remove the static classifier from Line 6 and recompile, I see a warning: warning: address of stack memory associated with local variable 'bin' returned This message means that the return value (on the stack) references a location that no longer exists. Here’s the output:

Enter an integer value, 0 to 255: 237
Binary value is

The char array must be declared static or its contents are lost.

Pointers can be pushed to the stack, so returning a pointer’s value (address) doesn’t require that the pointer be static. The pointer’s memory must be allocated, of course, as copying an array’s base to a pointer just returns the address of unallocated memory, which is bad.

No, to retain a string created in a function, its memory must be allocated within the function, as this improvement to the code demonstrates:

2022_07_23-Lesson-b.c

#include <stdio.h>
#include <stdlib.h>

char *binString(unsigned char n)
{
    const int width = 8;        /* 8-bit bytes */
    char *bin;        /* string storage */
    int x;

    /* allocate storage */
    bin = malloc( width * sizeof(char) +1 );
    if( bin==NULL )
        exit(1);

    /* fill storage */
    for(x=0;x<width;x++)
    {
        bin[x] = n & 0x80 ? '1' : '0';
        n <<= 1;
    }
    bin[width] = '\0';

    return(bin);
}

int main()
{
    int value;

    printf("Enter an integer value, 0 to 255: ");
    scanf("%d",&value);
    printf("Binary value is %s\n",binString((unsigned char)value));

    return(0);
}

The char pointer bin (Line 7) need not be static. Its memory is allocated at Line 11. The address is saved, which is returned from the function intact.

Unlike other functions where memory is allocated, you do not want to free this memory in the function! Wait until after you’re done using the string. If this program didn’t quit immediately after output, I would set a free() statement in the code to release the allocated memory. Otherwise, the string can be used outside the binString() function as you wish, no need to declare it static.

Leave a Reply