我正在写一个C程序。在第一行,我有
typedef float m_elem[NMAX][NMAX][3];
m_elem asa_m;
m_elem asa_mi[100];
然后,进行一些计算。此时,每次运行并根据输入,我将代码更改为NMAX值,然后重新编译并运行它。对于低于500的NMAX值,程序运行正常,但是对于更高的NMAX值(我需要一些输入文件),我得到的只是分段错误。
你建议我在这做什么?我读过关于学习valgrind的内容,但在这种情况下我想知道是否只是为了让程序处理更大的矩阵而改变编译选项会有所帮助
由于
答案 0 :(得分:6)
你可能用完了堆栈空间。
在NMAX = 500时,asa_mi
变量需要500 * 500 * 3 * 100 * 4字节,或大约300 MB。大多数操作系统都不允许堆栈很大,因此您可能需要检查系统的限制。
您是否尝试使用malloc()
而不是从堆中分配它?
答案 1 :(得分:1)
我的猜测是你的堆栈内存不足。 我建议在处理大量数据时动态分配内存
答案 2 :(得分:0)
像其他人一样说这可能是一个堆栈问题。如果array是某个函数的局部变量,那么很可能就是这种情况。这将失败,因为CPU从堆栈指针索引的能力有限,或者堆栈分配失败的方式类似于无限递归带来的堆栈溢出。后者会导致分段错误,因为系统对您已经定义的堆栈空间有一个上限,或者因为某些原因它自动拒绝为它自动分配。这可能因不同的操作系统而异。如果CPU的堆栈索引不仅受到限制而是被破坏,前者只会导致分段错误,导致STACKPOINTER偏移产生错误的地位;我不知道有任何CPU有这个问题,但它是可能的。考虑使用静态,全局或动态(malloc)数组,这应该避免这个问题。
这也可能是与NMAX常量的不一致使用相关的问题。你可能已经为那里的NMAX滑动设置了一些硬编码值,当你使用其他(更大)值时,你最终会超越它。
同样,如果/当NMAX很大时,你可能只有一个数组索引溢出只会导致分段错误。由于NMAX用作m_elem数组的2维大小,因此它的增长相对于NMAX呈指数增长。对于较小的NMAX值,它可以全部驻留在一个存储器页面中,并且由于OS通常通过页面跟上程序的存储器,所以溢出可能不会导致分段错误。随着NMAX变大,可能需要更多内存页来包含它。随着数组的增长(以指数方式),索引超出边界错误的可能性会进入不包含数组任何部分且可能根本不属于程序部分的内存页(或者至少不是可写部分)。如果您将3D阵列想象为高度为3,长度为NMAX,宽度为NMAX的城堡墙,并且该城堡的一面墙很薄并且容易被破坏,那么每次增加NMAX时,您只需将所有墙壁都加长,包括那个有缺陷的墙,所以你的城堡里有更多的墙。