gpt4 book ai didi

c - 'Segmentation fault (core dumped) '是什么原因

转载 作者:行者123 更新时间:2023-11-30 19:26:14 31 4
gpt4 key购买 nike

我编写了一个程序来使用递归查找数字的素因数。我收到运行时错误。原因是什么?

#include<stdio.h>

int main () {
int num , i = 2 ;
printf ( " Enter the number to find the prime factors\n ") ;
scanf ( "%d", &num ) ;
printf ( " The factors are :\n") ;
pf ( num , i ) ;
}

int pf ( int num , int i){
if ( num % i == 0 ){
if ( checkprime(i) == 1){
printf ( " %d " , i ) ;
num = num / i ;
}
}
if ( num > 1 ){
i++ ;
pf ( num , i ) ;
}
}

int checkprime ( int i){
int j ;
if (i==2)
return 1 ;
for ( j = 2 ; j < i ; j++ ){
if ( (i % j) == 0 )
return 0 ;
else
return 1 ;
}
if ( i==j )
return 1 ;
}

示例运行:

Enter the number to find the prime factors
12
The factors are :
Segmentation fault (core dumped)enter code here

最佳答案

这看起来像是您想要自己解决的学习练习,所以我不会为您编写代码。 (如果您尝试将此处的示例代码插入到您的程序中而不进行重构,它将无法工作。)

本着授之以鱼的精神,你应该做的第一件事是在不进行优化的情况下进行编译,使用调试符号,并打开所有警告。在 gcc/clang/icc 上,其标志类似于:

-std=c11 -Wall -Wextra -Wpedantic -Wconversion -g

这段代码甚至不应该编译。你不断地陷入到一个不 return 的函数的末尾。 void类型,但没有 return 失败陈述。不仅如此,您定义 pf()checkprime()在没有原型(prototype)的情况下调用它们之后!这不是唯一的错误,但让我们从这里开始。

从技术上讲,你应该有一个 return来自main() ,也是如此,但很多程序都没有这样做,以至于 C 委员会只是屈服并说它是可选的。

捕获错误的下一步是在调试器中加载程序,在要调试的函数上放置断点,然后单步执行它。

当你这样做时,你会发现如果你给它,程序进入无限循环,比方说,4 ,如果你确实给它一个终止的答案,例如 pf(1, 2) ,它将穿过所有 if block 并且永远不会到达 return声明。

所以你需要调试你的算法,但首先,你需要确保通过你的函数的每条路径都达到 return陈述。 (如果您实际上不需要返回值,您也可以声明 void pf(int, int)

我喜欢这样做的一种方法(但在 C 中似乎并不常见)是编写 if -else -return?运算符,例如:

 return (num <= 1)     ? 1 :              // No more factors.
(num % i == 0) ? pf( num/i, i ) : // Prime factor, with possible multiplicity.
pf( num, i+1 ); // Not a factor. Keep looking.

这当然在这里不起作用,因为它从不打印因子。 (它基于函数式代码,不应该有像 I/O 这样的副作用。)修复它的一种方法是用 if 重写。/then/else 。另一种是将因子存储在数据结构(例如动态数组或链表)中,然后返回。另一种是在复数之前打印return 。另一种方法是让应该打印因子的分支调用一个相互递归函数,该函数打印然后调用 pf() 。一个你不应该做的非常丑陋的黑客行为是使用逗号运算符。选择您最喜欢的一个。

这样做的优点是尾递归,因此可能会进入无限循环,但不会导致堆栈溢出。

如果你不喜欢这种风格,一些商店用来防止这种错误发生的另一种方法是用嵌套if来编写函数。设置像 int to_return = UNSET; 这样的变量的 block 。然后,每个分支设置 to_return到适当的值,你可以用类似的东西来完成

if (foo)
to_return = 1;
else
to_return = f(i);

asseert(to_return != UNSET);
return to_return;
这样,编译器可以确保您从有效分支返回,或者如果您忘记沿某个路径设置返回值,编译器会崩溃并告诉您位置和原因,而不是“段错误(核心转储)”。 ”

关于c - 'Segmentation fault (core dumped) '是什么原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57816114/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com