相关疑难解决方法(0)

使用可变长度数组有任何开销吗?

使用可变长度数组有一些开销吗?可以在运行时通过命令行参数传递数组的大小吗?与自动和动态分配数组相比,为什么会引入它?

c arrays variable-length-array

46
推荐指数
2
解决办法
2万
查看次数

为什么GCC的VLA(可变长度数组)实现中有数字22?

int read_val();
long read_and_process(int n) {
    long vals[n];
    for (int i = 0; i < n; i++)
        vals[i] = read_val();
    return vals[n-1];
}
Run Code Online (Sandbox Code Playgroud)

x86-64 GCC 5.4编译的汇编语言代码为:

read_and_process(int):
        pushq   %rbp
        movslq  %edi, %rax
>>>     leaq    22(,%rax,8), %rax
        movq    %rsp, %rbp
        pushq   %r14
        pushq   %r13
        pushq   %r12
        pushq   %rbx
        andq    $-16, %rax
        leal    -1(%rdi), %r13d
        subq    %rax, %rsp
        testl   %edi, %edi
        movq    %rsp, %r14
        jle     .L3
        leal    -1(%rdi), %eax
        movq    %rsp, %rbx
        leaq    8(%rsp,%rax,8), %r12
        movq    %rax, %r13
.L4:
        call    read_val()
        cltq …
Run Code Online (Sandbox Code Playgroud)

c assembly gcc x86-64 variable-length-array

14
推荐指数
1
解决办法
887
查看次数

C++中的可变长度数组开销?

看看这个问题:为什么C/C++编译器在编译时需要知道数组的大小?它来到我身边,编译器实现者应该有一些时间来弄清楚它(它是C99标准的一部分,那是10年前)并提供有效的实现.

然而,(从答案中)似乎仍然被认为是昂贵的.

这让我感到惊讶.

当然,我理解静态偏移在性能方面比动态偏移要好得多,并且不像一个建议我实际上不会让编译器执行数组的堆分配,因为这可能会花费更多[这没有被测量;)]

但我仍然对所谓的成本感到惊讶:

  • 如果一个函数中没有VLA,那么就我所见,不会有任何代价.
  • 如果有一个单独的VLA,那么可以在所有变量之前或之后放置它,因此获得大部分堆栈帧的静态偏移量(或者在我看来,但是我对堆栈管理并不精通) )

当然,问题出现在多个VLA上,我想知道是否有专用的VLA堆栈可行.这意味着VLA将由计数和指针(因此已知大小)表示,并且在辅助堆栈中采用的实际内存仅用于此目的(因此也是堆栈).

[改述]

如何在gcc/VC++中实现VLA?

成本真的令人印象深刻吗?

[结束改写]

在我看来,它只能比使用a vector,即使现有的实现更好,因为你不会产生动态分配的代价(以不可调整大小为代价).

编辑:

有部分反应在这里,但是比较沃拉斯传统阵列似乎不公平.如果我们事先知道尺寸,那么我们就不需要VLA了.在同一个问题中,AndreyT给出了一些关于实现的指示,但它并不像我想的那样精确.

c++ variable-length-array

13
推荐指数
1
解决办法
1078
查看次数

编译器如何处理可变长度数组

这似乎是一个初学者的问题,但我对编译器通常创建变量维数组的方式感兴趣,就像在下面的程序中一样.

#include<iostream>

int main(){
  int n;
  std::cin>>n;
  int a[n];
}
Run Code Online (Sandbox Code Playgroud)

根据我的学习,在C中,所有初始化值都必须是常量,这样编译器就知道要在函数内保留多少内存,通常是通过减去堆栈指针来容纳数组所包含的元素数.

这对我来说很有意义.但是,我不太明白编译器如何处理上述程序,因为它似乎与G ++(MinGW)一起工作,但是在C,Microsoft的C++编译器中失败了.我怀疑GCC通过非标准扩展在堆上分配内存,但我不确定.

此外,微软的编译器并不因标准兼容而闻名,所以如果它对待上述程序的方式实际上可能出错,我也不会感到惊讶.

c c++ templates visual-c++ c++11

10
推荐指数
2
解决办法
1995
查看次数

内存的价值是什么?

问题1:我的朋友问我一个问题,我想证明我的理解是正确的。如果我声明一个特定大小的数组,但不指定每个元素的值,则将其打印出来,得到全0。但这是使它们正确为0的编译器吗?我只需要声明一个X大小的数组,就可以分配一个正确大小的连续块吗?我不应该指望它们始终为零,而应自己手动对其进行初始化。

问题2:我在留言板上看到,较新的c ++允许您声明具有用户定义大小的数组。这对我来说没有意义,我一直认为需要在编译时就知道它。怎么了 这是语法糖吗?到底发生了什么事?

#include <iostream>

using namespace std;

void question2()
{
    int userInput;
    cin >> userInput;

    int anotherArray[userInput];
}

int main()
{
    int array[5];

    for (int i = 0; i < 5; i++) {
        cout << array[i] << endl;
    }
    cout << endl;

    question2();
}
Run Code Online (Sandbox Code Playgroud)

我希望从main发出混乱的输出,并显示类似“ userInput not const”之类的错误,但是我得到0 0 0 0 0和用户输入,并且进程在2.857秒后退出,返回值为0

c++

2
推荐指数
1
解决办法
79
查看次数

堆栈上大小可变的数组

据我了解,在C和C ++中,我们创建在堆栈上大小在编译时已知的数据结构,并使用堆(malloc-free / new-delete)处理大小在编译时未知的数据,是在运行时决定的。为什么,我的g ++编译器允许我执行类似以下代码段的操作。

int main(void)
{
    int n ;
    cin >> n ; // get the size of array.
    int arr[n] ; // create a variable sized array.
    .... do other stuff ...
}
Run Code Online (Sandbox Code Playgroud)

具体来说,在数组的情况下:
数组在堆栈上分配了一个连续的内存块,并且在堆栈上上下都有变量,因此必须知道数组的大小,以便堆栈上数组上方的变量,数组本身以及堆栈上数组下方的变量都可以整齐地放入内存。那么如何在堆栈上实现可变大小的数组呢? 为什么甚至有必要?为什么我们不能仅将堆用于可变大小的缓冲区?

编辑:
我从评论中了解到,关于VLA是否为标准,C和C ++有不同的规则,而且尼尔·巴特沃思(Neil Butterworth)的评论指出,同时询问两种语言通常不是一个好主意。谢谢大家,因此我打算从问题中删除C标签,因为我打算主要询问C ++,这从代码片段语法可以明显看出。抱歉造成您的困惑,也感谢您的答复。

c++ arrays stack

0
推荐指数
1
解决办法
649
查看次数

标签 统计

c++ ×4

c ×3

variable-length-array ×3

arrays ×2

assembly ×1

c++11 ×1

gcc ×1

stack ×1

templates ×1

visual-c++ ×1

x86-64 ×1