-2

Is it possible to allocate a variable length array to the stack in one function from another function?

One way that works is to just allocate the largest possible size up front, but I'm wondering if there is a way to avoid this.

void outside_function(){

char[] place_to_allocate_stack_array;

size_t array_size = allocate_and_fill_array(place_to_allocate_stack_array);

//do stuff with the now allocated variable length array on stack

}

size_t allocate_and_fill_array(char* place_to_allocate){

//does some stuff to determine how long the array needs to be
size_t length= determine_length();
//here I want to allocate the variable length array to the stack,
//but I want the outside_function to still be able to access it after
//the code exits allocate_and_fill_array
place_to_allocate[length];
//do stuff to fill the array with data
return length;

}

size_t determine_length(){
////unknown calculations to determine required length

}
  • 7
    *but I'm wondering if there is a way to avoid this.* `std::string` and `std::vector` are how you avoid this. – NathanOliver Feb 08 '19 at 22:40
  • Latest standard supports vsa (compiler feature), but what for? use vector. Avoid such inter-function stuff. – Michael Chourdakis Feb 08 '19 at 22:41
  • You cannot resize an array on the stack. Once you allocate it, it's allocated. – user4581301 Feb 08 '19 at 22:42
  • with std::vector, can I ensure that all memory allocations are on the stack? – user3738579 Feb 08 '19 at 22:50
  • No. That's not how std::vector works. But why exactly it's so important where std::vector allocates its memory? What difference does it make? – Sam Varshavchik Feb 08 '19 at 22:52
  • My (incorrect?) understanding was that doing a heap allocation was significantly more expensive performance-wise than stack. This was the reason to avoid vector in the first place. – user3738579 Feb 08 '19 at 22:53
  • It is true heap allocation is more expensive but if you don't know until run time how much memory you need, you have to heap allocation. – NathanOliver Feb 08 '19 at 22:57
  • https://stackoverflow.com/questions/43857625/variable-sized-array-on-the-stack, this seems to imply that you can stack allocate a variable length array, who's size is determined at runtime? – user3738579 Feb 08 '19 at 22:59
  • 1
    That be a Variable Length Array. They are not supported by the C++ Standard for [many good reasons](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard). Some compilers allow them anyway. Regardless, once created it cannot be resized so you can't pass it into a function and resize it. It is also impossible to return should you create it and size it inside a function and then try to hand it back to the caller. In general raw arrays suck. They solve the problems of the 1970s very well, but they don't fare so well with the problems of the 2010s. – user4581301 Feb 09 '19 at 00:21
  • http://wiki.c2.com/?PrematureOptimization – stark Feb 09 '19 at 14:44

1 Answers1

0

No, even ignoring the concerns people have about using variable-length arrays (VLAs). You are trying to accomplish too much in a single function. Step back a bit and look at what you are asking.

For consistency and to get away from arrays, I'm going to rename some things. Consider this version of your setup:

class X; // instead of "char []" so we can drop the VLA baggage

size_t inner_function(X & data) { // was "allocate_and_fill_array"
    // Determine how data should be allocated
    // Do stuff with data
}

void outer_function() {
    X data;
    size_t data_size = inner_function(data);
}

Requirement #1: The inner function needs access to a variable declared in the outer function. This requires that the variable be passed as a parameter to the inner function. This in turn requires that the inner function be called after the variable is declared.

Requirement #2: The inner function determines how data should be allocated (which happens at the point of declaration). This requires that the inner function be called before the variable is declared.

These requirements have contradictory prerequisites. Not possible.


I am led to the question: what led you to this approach? You already wrote a separate determine_length function. Let outside_function call that, declare the VLA, then pass the VLA and the length to the inner function. Much simpler conceptually.

size_t determine_length() {
    // unknown calculations to determine required length
}

void fill_array(char* stack_array, size_t length) {
    //do stuff to fill the array with data
}

void outside_function(){
    size_t length = determine_length();
    char stack_array[length];
    fill_array(stack_array, length);
    //do stuff with the variable length array on stack
}

Still, this obsession with getting the data on the stack is probably premature. While it is true that heap storage is more expensive than stack storage, the difference is often not worth worrying about. Get your program working before jumping through hoops to tweak performance. Focus on robustness. Only spend time on a performance bottleneck after it has been identified by a profiler.

JaMiT
  • 14,422
  • 4
  • 15
  • 31