Передача указателя, а затем выделение массива переменной длины в стек - PullRequest
0 голосов
/ 09 февраля 2019

Можно ли выделить массив переменной длины для стека в одной функции из другой функции?

Один из способов, который работает, это просто выделить максимально возможный размер заранее, но мне интересно, есть лиэто способ избежать этого.

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

}

1 Ответ

0 голосов
/ 09 февраля 2019

Нет, даже не обращая внимания на озабоченность людей по поводу использования массивов переменной длины (VLA).Вы пытаетесь достичь слишком многого в одной функции.Сделайте шаг назад и посмотрите на то, что вы спрашиваете.

Для последовательности и для того, чтобы уйти от массивов, я собираюсь переименовать некоторые вещи.Рассмотрим эту версию вашей установки:

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);
}

Требование № 1: Внутренняя функция нуждается в доступе к переменной, объявленной во внешней функции.Это требует, чтобы переменная передавалась как параметр внутренней функции.Это, в свою очередь, требует, чтобы внутренняя функция вызывалась после объявления переменной.

Требование № 2: Внутренняя функция определяет, как следует распределить data (что происходит в точкедекларация).Это требует вызова внутренней функции до объявления переменной.

Эти требования имеют противоречивые предпосылки.Невозможно.


У меня возникает вопрос: что привело вас к такому подходу?Вы уже написали отдельную функцию determine_length.Пусть outside_function вызовет это, объявит VLA, затем передаст VLA и длину внутренней функции.Концептуально гораздо проще.

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
}

Тем не менее, эта одержимость получением данных в стеке, вероятно, преждевременна .Несмотря на то, что динамическое хранилище дороже стекового хранилища, о разнице часто не стоит беспокоиться.Получите вашу программу, прежде чем прыгать через обручи, чтобы настроить производительность.Сосредоточиться на надежности.Тратьте время на узкие места производительности только после того, как они были определены профилировщиком.

...