c++ - 大小可变的函数中数组的内存注意事项

标签 c++ arrays

我将数组的大小作为变量而不是实际数字。对于我的程序,我用不同的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/

相关文章:

c++ - 命名空间和静态类成员链接

java - 在Java中随机化一组重复数组而不重复元素

java - 如何在 Java 中连接两个 float 数组?

java 枚举与数组属性

c# - 字符串反向应用程序不工作 - 索引超出数组范围

java - 你如何调用一个数组

c++ - 如何修改已编译 DLL 中的函数

c++ - 有没有比这样运行 255 个线程更快速、更有效的方法? CPP

c++ - WaitForSingleObject 不起作用

c++ - 什么在 CUDA : global memory write + __threadfence() or atomicExch() to global memory? 中更快