【问题标题】:Passing pointer and then allocating variable length array to stack传递指针,然后将可变长度数组分配到堆栈
【发布时间】:2019-02-08 22:38:58
【问题描述】:

是否可以在一个函数中从另一个函数向堆栈分配可变长度数组?

一种可行的方法是预先分配尽可能大的大小,但我想知道是否有办法避免这种情况。

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

}

【问题讨论】:

  • 但我想知道是否有办法避免这种情况。 std::stringstd::vector 是避免这种情况的方法。
  • 最新标准支持 vsa(编译器特性),但是有什么用呢?使用向量。避免这种跨功能的东西。
  • 您无法调整堆栈中数组的大小。一旦你分配它,它就被分配了。
  • 用std::vector,能保证所有的内存分配都在栈上吗?
  • 这是一个可变长度数组。 many good reasons 的 C++ 标准不支持它们。一些编译器无论如何都允许它们。无论如何,一旦创建它就无法调整大小,因此您无法将其传递给函数并调整其大小。如果您在函数中创建它并调整它的大小,然后尝试将其交还给调用者,也无法返回。一般来说,原始数组很烂。他们很好地解决了 1970 年代的问题,但他们在 2010 年代的问题上表现不佳。

标签: c++ arrays variable-length-array


【解决方案1】:

不,即使忽略人们对使用可变长度数组 (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
}

不过,这种在堆栈上获取数据的痴迷可能是premature。虽然堆存储确实比堆栈存储更昂贵,但差异通常不值得担心。让您的程序运行起来,然后再跳槽以调整性能。专注于稳健性。仅在性能瓶颈被分析器识别后才花时间处理。

【讨论】:

    猜你喜欢
    • 2013-04-14
    • 2012-01-18
    • 2023-03-30
    • 2016-01-06
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 2021-12-04
    • 2017-05-06
    相关资源
    最近更新 更多