由于我通常使用的C++编译器允许可变长度数组(例如,数组取决于运行时大小),我想知道是否有类似std::array可变大小的东西?当然std::vector是可变大小,但它在堆上分配,并根据需要重新分配.
我喜欢堆栈分配的数组,其大小在运行时定义.是否有任何std可能具有此功能的模板?也许使用std::vector固定的最大尺寸?
将可变长度列表的Python序列隐式转换为NumPy数组会导致该数组为object类型.
v = [[1], [1, 2]]
np.array(v)
>>> array([[1], [1, 2]], dtype=object)
Run Code Online (Sandbox Code Playgroud)
试图强制其他类型将导致异常:
np.array(v, dtype=np.int32)
ValueError: setting an array element with a sequence.
Run Code Online (Sandbox Code Playgroud)
通过使用给定的占位符填充"缺失"值,获得int32类型的密集NumPy数组的最有效方法是什么?
从我的样本序列中v,我想得到类似的东西,如果0是占位符
array([[1, 0], [1, 2]], dtype=int32)
Run Code Online (Sandbox Code Playgroud) 这是一个简短的C程序,它提示用户输入一个数字,创建一个具有该大小的可变长度的int数组,然后使用指针算法来跳过已分配的元素:
#include <stdio.h>
int main() {
/* Read a size from the user; inhibits compiler optimizations. */
int n;
scanf("%d", &n); // Yes, I should error-check. :-)
/* We now have a VLA. */
int arr[n];
/* What is the type of &arr? */
void* ptr = (&arr) + 1;
/* Seems like this skipped over things properly... */
printf("%p\n", arr);
printf("%p\n", ptr);
}
Run Code Online (Sandbox Code Playgroud)
如果您愿意,可以在ideone上试试这个.输出表明该行
void* ptr = (&arr) + 1;
Run Code Online (Sandbox Code Playgroud)
获取可变长度数组中arr所有n元素的步骤,并以大小识别的方式执行.
如果这不是一个可变长度数组,我会完全放心它是如何工作的.编译器会知道它的类型arr …
我正在使用MinGW来编译C++ 11,我发现这不会引发错误:
int S;
cin>>S;
char array[S];
Run Code Online (Sandbox Code Playgroud)
虽然这样做("'数组'的存储大小未知"):
char array[];
Run Code Online (Sandbox Code Playgroud)
对我来说,第一种情况下的大小也是未知的,因为它取决于用户输入的内容.
据我所知,自动数组在编译时分配在堆栈内存中.那么为什么第一个例子不会失败呢?
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/C++编译器在编译时需要知道数组的大小?它来到我身边,编译器实现者应该有一些时间来弄清楚它(它是C99标准的一部分,那是10年前)并提供有效的实现.
然而,(从答案中)似乎仍然被认为是昂贵的.
这让我感到惊讶.
当然,我理解静态偏移在性能方面比动态偏移要好得多,并且不像一个建议我实际上不会让编译器执行数组的堆分配,因为这可能会花费更多[这没有被测量;)]
但我仍然对所谓的成本感到惊讶:
当然,问题出现在多个VLA上,我想知道是否有专用的VLA堆栈可行.这意味着VLA将由计数和指针(因此已知大小)表示,并且在辅助堆栈中采用的实际内存仅用于此目的(因此也是堆栈).
[改述]
如何在gcc/VC++中实现VLA?
成本真的令人印象深刻吗?
[结束改写]
在我看来,它只能比使用a vector,即使现有的实现更好,因为你不会产生动态分配的代价(以不可调整大小为代价).
编辑:
有部分反应在这里,但是比较沃拉斯传统阵列似乎不公平.如果我们事先知道尺寸,那么我们就不需要VLA了.在同一个问题中,AndreyT给出了一些关于实现的指示,但它并不像我想的那样精确.
我对可变长度数组感到担忧.当我想动态分配一个数组时,如果无法分配足够的内存,我将得到null,我可以在程序中正确响应.对于可变长度数组,我没有得到这些信息.我该怎么办?
以下代码在gcc 4.8和Clang 3.2下编译:
int main()
{
int size = 10;
int arr[size];
}
Run Code Online (Sandbox Code Playgroud)
C++标准的8.3.4/1表示数组的大小必须是一个整数常量表达式,这size似乎不是.这是两个编译器中的错误,还是我错过了什么?
最新的VC++ CTP用这个有趣的消息拒绝代码:
error C2466: cannot allocate an array of constant size 0
Run Code Online (Sandbox Code Playgroud)
有趣的是,它似乎认为size是零.但至少它拒绝了代码.gcc和Clang应该不一样吗?
c++ arrays compile-time-constant variable-length-array c++11
我试图理解将多维数组传递给c中的函数的"最佳实践"(或实际上是任何实践).当然这取决于应用程序,因此我们考虑编写一个函数来打印可变大小的2D数组.特别是,我对如何printArry(__, int a, int b)在下面的代码中编写函数感兴趣.我省略了第一个参数,因为我不确定应该是什么.
void printArry(_____, int a, int b){
/* what goes here? */
}
int main(int argc, char** argv){
int a1=5;
int b1=6;
int a2=7;
int a2=8;
int arry1[a1][b1];
int arry2[a2][b2];
/* set values in arrays */
printArry(arry1, a1, b1);
printArry(arry2, a2, b2);
}
Run Code Online (Sandbox Code Playgroud) c arrays pointers multidimensional-array variable-length-array
根据cppreference:
如果表达式的类型是可变长度数组类型, 则计算表达式,并在运行时计算它计算的数组的大小.
这意味着:如果表达式的类型是VLA类型,则计算表达式.例如:
#include <stdio.h>
int main() {
int i = 0;
int a[i];
printf("%zu\n",sizeof(a[i++]));
printf("%d\n",i); // Here, print 0 instead of 1
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以,根据参考,这里i变成了1.但是,使用我的GCC编译器,i打印为0.
请参阅Wandbox演示.