【问题标题】:C Segmentation Fault With Printf() and Scanf()Printf() 和 Scanf() 的 C 分段错误
【发布时间】:2012-04-13 15:57:54
【问题描述】:

我是 C 的新手,遇到了一个我无法理解的分段错误。我有以下程序,它试图计算严格正数的因子数:

#include <stdio.h>
#include <math.h>

int numberOfFactors (int number, int factor) {
    if (number % factor == 0) {
        number = number/factor;
        return numberOfFactors(number, factor) + 1;
    } else {
        return 0;
    }
}

int check (int x) {
    if (x>0) {
        return 1;
    } else {
        return 0;
    }
}

int main(void) {
    int number;
    printf("Please enter a positive integer n such that n >= 1: ");
    scanf("%d", &number);
    if (check(number)){
        int i;
        for (i=1; i<=number; i++) {
            int factors;
            factors = numberOfFactors(number, i);
            printf("%d^%d ", i, factors);
        }
    }
    return 0;
}

在 main() 中输入整数并在这些行之后输入 ENTER 后立即发生分段错误:

printf("Please enter a positive integer n such that n >= 1: ");
scanf("%d", &number);

这些行中的什么导致了分段错误,我可以做些什么来避免它?

【问题讨论】:

  • 你试过在调试器下运行吗?它可能会停在导致故障的确切行。
  • 不,我实际上只是在 TextWrangler 中输入此内容,然后通过 FTP 将其传送到我的学校 Linux 环境。

标签: c segmentation-fault


【解决方案1】:

如果您尝试除以因子一,您的递归不会停止。

只要让因子永远不会是 1:

    for (i=2; i<=number; i++) {
        int factors;
        factors = numberOfFactors(number, i);
        printf("%d^%d ", i, factors);
    }

我应该说为什么会出现段错误:这是因为每个函数调用都会将当前程序计数器(您当前所在的程序中的位置)和函数参数推送到堆栈(也称为调用堆栈)上,其中堆栈相对较小用于函数调用和局部变量的内存块。

因此,如果您将筹码推得太紧,它就会倒下。游戏结束,也就是段错误;)

【讨论】:

    【解决方案2】:

    你可能对这个递归有问题:

    int numberOfFactors (int number, int factor) {
        if (number % factor == 0) {
            number = number/factor;
            return numberOfFactors(number, factor) + 1;
        } else {
            return 0;
        }
    }
    

    将您的 numberOfFactors 更改为:

    int numberOfFactors (int number)
    {
        int i=1;
        int ret=0;
        for(;i<=number;i++) {
            if (number%i == 0) {
                ret++;
            }
        }
        return ret;
    }
    

    然后,更改这部分:

    if (check(number)){
        int i;
        for (i=1; i<=number; i++) {
            int factors;
            factors = numberOfFactors(number, i);
            printf("%d^%d ", i, factors);
        }
    }
    

    更简单的,比如:

    if (check(number)){
        factors = numberOfFactors(number);
        printf("%d^%d ", number, factors);
    }
    

    【讨论】:

    • 我不认为它到达那里,因为我在那里扔了一些 printf 语句来检查。
    • 事实上,我在 main 中的 scanf 之后立即抛出了一个 printf ,它甚至没有做到那么远。
    • @canton 这可能会产生很大的误导。 stdout 默认为行缓冲。因此,程序可能会因仍缓冲的数据而崩溃。最好的选择是调试器,但如果您要使用printf(),请确保字符串以\n 或fflush(stdout); 结尾
    • @canton:正如 FatalError 在他/她的评论中所说的那样。
    猜你喜欢
    • 1970-01-01
    • 2013-10-12
    • 2013-03-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多