我将数组的大小作为变量而不是实际数字。对于我的程序,我用不同的diagonalize
值调用函数array_size
3次-是为array_size
的每个值分配和释放数组,还是在程序执行期间仅使用和覆盖一个数组?代码如下。制作三个单独的diagonalize
函数会更好,每个函数在内部声明一个数组,数组的大小由唯一的全局常数给定?不幸的是,我不得不使用数组而不是 vector 。
#include <mkl.h>
#include "mkl_lapacke.h"
void diagonalize(unsigned long long int array_size) {
lapack_complex_double z[array_size];
}
细节:我正在使用icpc -std = c++ 11 -L $ {MKLROOT} / lib / intel64 -lmkl_intel_lp64 -lmkl_core -lmkl_sequential -lpthread -ldl 10_site_main.cpp进行编译
icpc版本19.0.4.243(与gcc版本4.8.5兼容)
最佳答案
在
void diagonalize(unsigned long long int array_size) {
lapack_complex_double z[array_size];
}
z
是C99的可变长度数组(VLA)功能,C++标准没有此功能,但是某些C++编译器支持它作为内置类型的扩展。在Linux上,默认堆栈大小为8MB左右,因此使用
unsigned long long int
作为array_size
是一个大问题,而unsigned
就足够了。值得注意的是,Linux内核在2018年摆脱了所有VLA,因为它可以使堆栈下溢/溢出并破坏堆栈,从而为内核利用提供了攻击载体。
它是否使堆栈下溢取决于调用函数时有多少可用堆栈空间,并且取决于当前调用链。在一个调用链中,可能有很多堆栈空间,在另一个调用链中则没有那么多。这使得很难保证或证明该功能始终具有足够的堆栈空间用于VLA。不使用VLA消除了使堆栈下溢/溢出并破坏堆栈的机会,这是利用漏洞的最流行和最简便的途径。
would the array be allocated and deallocated for each value of
array_size
, or would only one array be used and overwritten during the program?
它是在每次调用时在函数堆栈中分配的自动函数局部变量。分配保留堆栈空间,通常需要一条CPU指令,如
sub rsp, vla-size-in-bytes
on x86-64。当函数返回时,其所有自动函数变量将不复存在。有关详细信息,请参见https://en.cppreference.com/w/cpp/language/storage_duration,自动存储持续时间。
Would it just be better to make three separate diagonalize functions which each internally declare an array with the size given by a unique global constant?
不会有什么区别,因为当函数返回时,所有自动变量都将被销毁并不再存在。
关于c++ - 大小可变的函数中数组的内存注意事项,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63942932/