什么是VLA的地步呢? [英] What's the point of VLA anyway?

查看:142
本文介绍了什么是VLA的地步呢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我明白了什么变长数组以及它们是如何实现的。这个问题是他们为什么存在。

I understand what variable length arrays are and how they are implemented. This question is about why they exist.

我们知道,沃拉斯只是功能块(或样机)内允许的,他们基本上无法在任何地方,但在栈上(假设正常执行):C11,6.7.6.2-2:

We know that VLAs are only allowed within function blocks (or prototypes) and that they basically cannot be anywhere but on the stack (assuming the normal implementation): C11, 6.7.6.2-2:

如果一个标识符被声明为具有可变类型,它应是一个普通的
  标识符(如6.2.3定义),没有联动,要么阻止范围或功能
  原型范围。如果一个标识符被声明为与静态或线程存储对象
  持续时间,不得具有可变长度数组类型。

If an identifier is declared as having a variably modified type, it shall be an ordinary identifier (as defined in 6.2.3), have no linkage, and have either block scope or function prototype scope. If an identifier is declared to be an object with static or thread storage duration, it shall not have a variable length array type.

让我们举一个小例子:

void f(int n)
{
    int array[n];
    /* etc */
}

有两种情况需要被照顾的:

there are two cases that need to be taken care of:


  • N'LT; = 0 ˚F的防范这一点,否则该行为是未定义:C11,6.7.6.2-5(重点煤矿):

  • n <= 0: f has to guard against this, otherwise the behavior is undefined: C11, 6.7.6.2-5 (emphasis mine):

如果大小是前pression不是整型常量前pression:如果在它发生
  声明在函数原型范围,如果它是由替换* 将被处理;除此以外,
  每次评估应当有一个时间值大于零。每个实例的大小
  可变长度数组类型的在其寿命期间不会改变。凡大小
  前pression是的sizeof 运算符的操作数的一部分,并且不断变化的价值
  大小当然pression不会影响操作的结果,它是未指定是否
  规模前pression进行评估。

If the size is an expression that is not an integer constant expression: if it occurs in a declaration at function prototype scope, it is treated as if it were replaced by *; otherwise, each time it is evaluated it shall have a value greater than zero. The size of each instance of a variable length array type does not change during its lifetime. Where a size expression is part of the operand of a sizeof operator and changing the value of the size expression would not affect the result of the operator, it is unspecified whether or not the size expression is evaluated.

N'GT; stack_space_left / element_size :有发现多少堆栈空间留给(因为没有这样的事情栈,只要标准而言)的标准方法。所以此测试是不可能的。唯一合理的解决办法是有一个predefined最大尺寸为 N ,说 N ,以确保栈溢出不会发生。

  • n > stack_space_left / element_size: There is no standard way of finding how much stack space is left (since there is no such thing as stack so long as the standard is concerned). So this test is impossible. Only sensible solution is to have a predefined maximum possible size for n, say N, to make sure stack overflow doesn't occur.

    在换句话说,程序员必须确保 0℃; N'LT; = N 供选择的某些 N 。然而,该方案应适用 n ==可ñ无论如何,所以人们可能也宣布与固定大小数组 N 而不是可变长度 N

    In other words, the programmer must make sure 0 < n <= N for some N of choice. However, the program should work for n == N anyway, so one might as well declare the array with constant size N rather than variable length n.

    据我所知,沃拉斯已替代的alloca (如这个答案),但实际上它们是同一个东西(在栈上分配可变大小的内存)。

    I am aware that VLAs were introduced to replace alloca (as also mentioned in this answer), but in effect they are the same thing (allocate variable size memory on stack).

    所以,问题是为什么没有的alloca ,因此存在VLA,为什么不自己去precated?使用沃拉斯的唯一安全的方式在我看来是有界的大小在这种情况下采取了正常的数组的最大大小始终是一个可行的解决方案。

    So the question is why did alloca and consequently VLA exist and why weren't they deprecated? The only safe way to use VLAs seem to me to be with a bounded size in which case taking a normal array with the maximum size is always a viable solution.

    推荐答案

    综观意见和答案,在我看来,当你知道通常您的输入不是太大(类似于知道你的递归沃拉斯是有用的可能不是太深),但你实际上并没有上限,你通常会忽略可能的堆栈溢出(类似于递归忽视他们)希望他们不会发生。

    Looking at the comments and the answers, it seems to me that VLAs are useful when you know that normally your input is not too big (similar to knowing your recursion is probably not too deep), but you don't actually have an upper bound, and you would generally ignore the possible stack overflow (similar to ignoring them with recursion) hoping they don't happen.

    这实际上可能不是一个问题,要么干脆,例如,如果你有无限的堆栈大小。

    It may actually be not an issue altogether either, for example if you have unlimited stack size.

    这是说,这里是另一个使用了他们,我发现,它实际上并不堆栈分配内存,但这样的动态多维数组更容易合作。我将通过一个简单的例子证明:

    That said, here's another use for them I have found which doesn't actually allocate memory on stack, but makes working with dynamic multi-dimensional arrays easier. I'll demonstrate by a simple example:

    #include <stdio.h>
    #include <stdlib.h>
    
    int main(void)
    {
        size_t n, m;
    
        scanf("%zu %zu", &n, &m);
    
        int (*array)[n][m] = malloc(sizeof *array);
    
        for (size_t i = 0; i < n; ++i)
            for (size_t j = 0; j < m; ++j)
                (*array)[i][j] = i + j;
    
        free(array);
        return 0;
    }
    

    这篇关于什么是VLA的地步呢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆