0

Context

I was experimenting with getting C strings in C++ without allocating memory on the heap and came across this in testing:

#include <stddef.h>
#include <stdlib.h>

char* get_empty_c_string(size_t length) {
    char buffer[length];
    char *string = buffer;

    for (size_t i = 0; i ^ length; i++) *(string + i) = '\0';

    return string;
}

int main(void) {
    char *string = get_empty_c_string(20u); // Allocated on heap?
                                            // or stack?
    return 0;
}

Question

Is the C string returned allocated on heap or stack?

As far as I know:

  • Heap allocation occurs with the calloc, malloc & realloc C standard functions or new & new[] C++ keywords.

  • Stack allocation in most other cases.

7
  • 4
    char buffer[length]; -- This is not valid C++. Commented Dec 13, 2019 at 2:45
  • Variable length array is valid only in C, not C++ as mentioned above. Commented Dec 13, 2019 at 2:47
  • And even if we are assuming that variable-length array such as this are valid in C++ or that the code is C, you are returning a pointer to stack-allocated memory that will be invalid as soon as the function returns. string is not usable in main. Commented Dec 13, 2019 at 2:48
  • I ran this code on GCC with all warning flags set using -Wall and this was not mentioned... Commented Dec 13, 2019 at 2:49
  • 2
    @Lapys GCC supports VLAs as compiler extension by default. In order for GCC to behave standard-conform, you need to add the -pedantic-errors flag. Commented Dec 13, 2019 at 2:50

3 Answers 3

1

The array buffer is a variable length array (VLA), meaning its size is determined at runtime. As a variable local to a function is resides on the stack. The pointer string then points to that array, and that pointer is returned. And because the returned pointer points to a local stack variable which goes out of scope, attempting to use that pointer will invoke undefined behavior.

Also, note that VLAs are a C only feature.

Sign up to request clarification or add additional context in comments.

Comments

1

There is no way in standard C++ to obtain runtime-sized memory of automatic storage duration (which usually maps to stack memory).

Therefore a proper string of any length cannot be obtained on the stack. You can only allocate a buffer with a maximal size and use strings up to that length in the program. (Something similar is usually done by std::string as so-called short string optimization.)

Furthermore, you cannot return pointers or references to variables with automatic storage duration from a function. When the function returns the variables are destroyed and the pointer/reference becomes invalid. You can only ever use the stack-allocation until the function returns. You can however return the variable by-value.

1 Comment

<i>Short string optimization</i>? Sounds like another interesting thing to learn
0

As @PaulMcKenzie points out, your implementation of get_empty_c_string() would fail to compile: In essence, arrays as temporary/instance variables of a function need to have a static size defined for them prior to compile time. This is because that volume of memory is pushed onto the stack at function invocation.

I can see that you're trying to have dynamic memory allocation as part of the function itself, which is why you need such heap-allocators.

1 Comment

Hmm, understood. Without the -pedantic-errors flags though, the code compiles freely; As @walnut says, GCC supports VLAs as compiler extensions by default apparently

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.