程序崩溃时出现分段错误,所以我用gdb运行它。我发现在运行时期间会覆盖一个类的成员。几个事实:
我检查了调试器停止的行 - 此行中访问的变量具有不同的内存地址。
一段gdb代码:
(gdb) p SrcVelField
$1 = (SNGM::FieldVector *) 0x555555a237a0
(gdb) p *SrcVelField
$2 = {MeshRef = 0x55555592e530, Values = {data_ = 0x555555a237f0}, NbVar = 3,
NbVal = 8820, VarName = {data_ = 0x55555592f000},
FieldName = "VelocityField"}
(gdb) p (*SrcVelField).NbVar
$3 = 3
(gdb) p &(*SrcVelField).NbVar
$4 = (unsigned int *) 0x555555a237b0
(gdb) watch -l *0x555555a237b0
Hardware watchpoint 2: -location *0x555555a237b0
(gdb) cont
Thread 1 "SNGM" hit Hardware watchpoint 2: -location *0x555555a237b0
Old value = 3
New value = -118991381
SNGM::GlobalEval<SNGM::FilterGaussian, 3u, 1u>::PerformGlobalEval ()
at ../SNGM/Numerics/GlobalEval.cpp:288
288 for (unsigned ii = 0; ii < nx; ii++){
(gdb) p &ii
$5 = (unsigned int *) 0x7fffffffc93c
(gdb) p &nx
$6 = (const unsigned int *) 0x7fffffffc950
我很高兴提示为什么(*SrcVelField).NbVar
的价值正在改变。
更新 在这一行中反汇编代码会产生下一个: - 有问题的rax值
(gdb) info registers
rax 0x555555a237b0 93824997275568
rbx 0x61a8 25000
及其指示
280 delete[] point;
0x0000555555595bcc <+1113>: cmpq $0x0,-0x58(%rbp)
0x0000555555595bd1 <+1118>: je 0x555555595adc
<PerformGlobalEvalEv._omp_fn.0(void)+873>
0x0000555555595bd7 <+1124>: mov -0x58(%rbp),%rax
0x0000555555595bdb <+1128>: mov %rax,%rdi
0x0000555555595bde <+1131>: callq 0x555555564758
0x0000555555595be3 <+1136>: jmpq 0x555555595adc
<PerformGlobalEvalEv._omp_fn.0(void)+873>
281 } //End for all particles
282
283 #pragma omp critical
0x0000555555595f5b <+2024>: callq 0x555555564ae8
0x0000555555595f78 <+2053>: callq 0x555555564a40
284 {
285
286 for (unsigned kk = 0; kk < nz; kk++){
0x0000555555595f60 <+2029>: movl $0x0,-0x15c(%rbp)
0x0000555555595f6a <+2039>: mov -0x15c(%rbp),%eax
0x0000555555595f70 <+2045>: cmp -0x148(%rbp),%eax
0x0000555555595f76 <+2051>: jb 0x555555595fed
<PerformGlobalEvalEv._omp_fn.0(void)+2170>
0x0000555555596005 <+2194>: addl $0x1,-0x15c(%rbp)
0x000055555559600c <+2201>: jmpq 0x555555595f6a
<PerformGlobalEvalEv._omp_fn.0(void)+2039>
287 for (unsigned jj = 0; jj < ny; jj++){
0x0000555555595fed <+2170>: movl $0x0,-0x158(%rbp)
0x0000555555595ff7 <+2180>: mov -0x158(%rbp),%eax
0x0000555555595ffd <+2186>: cmp -0x144(%rbp),%eax
0x0000555555596003 <+2192>: jb 0x555555596011
<PerformGlobalEvalEv._omp_fn.0(void)+2206>
0x0000555555596029 <+2230>: addl $0x1,-0x158(%rbp)
0x0000555555596030 <+2237>: jmp 0x555555595ff7
<PerformGlobalEvalEv._omp_fn.0(void)+2180>
288 for (unsigned ii = 0; ii < nx; ii++){
0x0000555555596011 <+2206>: movl $0x0,-0x154(%rbp)
0x000055555559601b <+2216>: mov -0x154(%rbp),%eax
0x0000555555596021 <+2222>: cmp -0x140(%rbp),%eax
0x0000555555596027 <+2228>: jb 0x555555596032
<PerformGlobalEvalEv._omp_fn.0(void)+2239>
=> 0x0000555555596177 <+2564>: addl $0x1,-0x154(%rbp)
答案 0 :(得分:2)
当堆栈/堆大小耗尽或数组索引超出范围时,这是常见的行为。检查堆栈和堆大小,并确认您没有超出它们。然后检查所有数组/列表实例,并验证它们是否受到保护以防止越界错误。