我正在将程序从fortran转换为C ++。
我的代码似乎运行正常,直到我添加此数组声明:
float TC[100][100][100];
然后当我运行它时,我得到一个分段错误错误。这个阵列应该只占用8Mb的内存,而我的机器只有3 Gb。这个声明有问题吗?我的c ++非常生疏。
答案 0 :(得分:3)
我猜测TC
被分配为自动局部变量。这意味着它存储在堆栈中。你没有得到4mb的堆栈内存,所以它导致堆栈溢出。
要解决此问题,请使用带有结构化容器的动态分配或new
。
答案 1 :(得分:3)
该数组大约4兆字节。如果这个定义在一个函数内(作为局部变量),那么编译器会尝试将它存储在堆栈上,而在大多数系统上都不会那么大。
Fortran编译器可能静态地分配它(除非明确标记为递归,否则不允许递归调用Fortran例程,因此局部变量的静态分配适用于非递归函数),因此错误不会发生在那里。
一个简单的修复方法是显式声明变量static,假设Fortran函数没有声明递归。但是,如果你试图从修订版本中递归调用该函数,这可能会让你迟到。因此,更好的解决方案可能是动态分配它。然而,这需要额外的时间,因此取决于代码的性质,可能会对您的性能造成太大影响(Fortran代码通常是性能很重要的数字代码)。
如果您选择将数组设置为静态,则可以建立防止意外递归调用的保护:
void yourfunction()
{
static bool active;
static float TC[100][100][100];
assert(!active);
active = true;
// your code
active = false;
}
答案 2 :(得分:0)
这看起来像基于堆栈的声明。尝试从堆中分配(即使用new运算符)。
答案 3 :(得分:0)
如果你在函数内部声明它作为局部变量,那么堆栈可能不足以适合数组。您可以尝试使用new
或malloc()
在堆中进行分配,或者,如果您的设计允许,则将其设置为全局变量。
答案 4 :(得分:0)
在C ++中,堆栈的空间有限。 MSVC默认此大小为1MB。如果堆栈使用超过1MB,则会发生段错误或堆栈溢出等。您必须将该结构移动到动态内存。要将它移动到动态内存,你需要这样的东西:
typedef float (bigarray)[100][100][100];
bigarray& TC() {
static bigarray* ptr = NULL;
if (ptr == NULL) {
ptr = new float[100][100][100];
for(int j=0; j<100; j++) {
ptr[j] = new float[100][100];
for(int i=0; i<100; i++)
ptr[j][i] = new float[100];
}
}
return *ptr;
}
这将在第一次访问动态内存时将结构分配为锯齿状数组。您可以从矩形数组中获得更多性能,但您必须更改类型:
typedef std::vector<std::array<std::array<float, 100>, 100> bigarray;
bigarray TC(100);
根据http://cs.nyu.edu/exact/core/doc/stackOverflow.txt,gcc / linux默认堆栈大小为8MB,这对于你的结构来说还不够大和 int main()
如果你真的想要,那么MSVC有标志,以增加堆栈大小高达32MB。 Linux有一个ulimit
命令可以将堆栈大小增加到32MB。