【问题标题】:why segmentation fault (cored dumped )?为什么分段错误(核心转储)?
【发布时间】:2017-01-26 09:37:58
【问题描述】:

我在编程网站上解决了一个问题,但是当我的输入 n = 2147483647 那么它给出分段错误(核心转储)?

int integerReplacement(int n) {
  if(n == 1)
    return 0;
  if(n%2 == 0)
  {
    return 1+integerReplacement(n/2);
  }
  else
  {
    int lMin = 1+integerReplacement(n-1);       
    int rMin = 1+integerReplacement(n+1);
    return lMin<rMin?lMin:rMin;
  }
}

【问题讨论】:

  • 堆栈溢出?
  • 当递归接收到您声明的参数2147483647 时,integerReplacement(n+1);未定义的行为,因为n 现在超出了整数范围。

标签: c recursion segmentation-fault


【解决方案1】:

正如 Weather Vane 正确指出的那样,INT_MAX + 1 会导致您出现未定义的行为。

你可以这样想办法:

gcc -g foo.c
gdb -q ./a.out
(gdb) r
Starting program: /tmp/a.out

Program received signal SIGSEGV, Segmentation fault.
0x00000000004004f5 in integerReplacement (n=<error reading variable: Cannot access memory at address 0x7fffff7fefec>) at foo.c:1
1   int integerReplacement(int n) {
(gdb) bt 6
#0  0x00000000004004f5 in integerReplacement (n=<error reading variable: Cannot access memory at address 0x7fffff7fefec>) at foo.c:1
#1  0x0000000000400522 in integerReplacement (n=-2) at foo.c:6
#2  0x0000000000400534 in integerReplacement (n=-1) at foo.c:10
#3  0x0000000000400522 in integerReplacement (n=-2) at foo.c:6
#4  0x0000000000400534 in integerReplacement (n=-1) at foo.c:10
#5  0x0000000000400522 in integerReplacement (n=-2) at foo.c:6
(More stack frames follow...)

(gdb) bt -10
#174684 0x0000000000400522 in integerReplacement (n=-16777216) at foo.c:6
#174685 0x0000000000400522 in integerReplacement (n=-33554432) at foo.c:6
#174686 0x0000000000400522 in integerReplacement (n=-67108864) at foo.c:6
#174687 0x0000000000400522 in integerReplacement (n=-134217728) at foo.c:6
#174688 0x0000000000400522 in integerReplacement (n=-268435456) at foo.c:6
#174689 0x0000000000400522 in integerReplacement (n=-536870912) at foo.c:6
#174690 0x0000000000400522 in integerReplacement (n=-1073741824) at foo.c:6
#174691 0x0000000000400522 in integerReplacement (n=-2147483648) at foo.c:6
#174692 0x0000000000400547 in integerReplacement (n=2147483647) at foo.c:11
#174693 0x0000000000400567 in main () at foo.c:18

所以你实际上最终会出现堆栈溢出(通常你的算法不应该重复超过 31 次,但由于有符号溢出最终会在用完堆栈之前重复 174693 次)。

【讨论】:

  • @RaviSingh 在大多数当前架构上,整数有 31 位(加上一个符号位)。这限制了在达到 0 或 1 之前您可以将其除以 2 的次数。
猜你喜欢
  • 2021-12-04
  • 2015-05-23
  • 2020-01-28
  • 1970-01-01
  • 1970-01-01
  • 2013-11-07
  • 1970-01-01
相关资源
最近更新 更多