【问题标题】:SIGSEGV, Segmentation fault in Windows although running fine in LinuxSIGSEGV,Windows 中的分段错误,尽管在 Linux 中运行良好
【发布时间】:2016-05-07 12:27:30
【问题描述】:
// 10001st prime
/*
 * By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13,
 * we can see that the 6th prime is 13.
 * What is the 10001st prime number?
 */

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

#define FIRST_NUM 2
#define START_COUNT 0

void prime(int num, int count)
{
    int i, flag=1;
    for(i=2; i<=sqrt(num); i++)
    {
        if(num%i==0)
        {
            flag=0;
            break;
        }
        flag=1;
    }
    if(flag)
    {
        count++;
        if(count==10001)
            printf("The 10001st prime number is %d\n", num);
    }
    if(count!=10001)
        prime(num+1, count);
}

int main(void)
{
    prime(FIRST_NUM, START_COUNT);
    return 0;
}

// Answer: 104743

我在两个平台上都使用了 CodeBlocksEclipse

它在 Linux 中运行良好,在 CodeBlocks 中,带有:

第 10001 个素数是 104743
进程返回 35 (0x23) 执行时间:0.0109 s

但不是在 Windows 中。

但是,当我尝试在 CodeBlocks(在 Windows 中)中调试它时,它给了我这个错误

程序收到信号SIGSEGV,分段错误
调用堆栈 为: 编号= #0 |地址= 77101566 |函数= msvcrt!modf() |文件= (C:\WINDOWS\SysWOW64\msvcrt.dll:??) 编号= #1 |地址=?? |功能= ?? () | File= (??:??) //我觉得这个不重要 :)

我尝试在 Internet 上搜索有关 SIGSEGV 错误的信息,但没有得到满意的结果。

请尽可能多地解释。 我将不胜感激。 :)

【问题讨论】:

  • 分段错误很可能指向未定义的行为,这也可能导致预期的行为。因此,如果它在一个操作系统下工作,但在另一个操作系统上不工作,则不能断定代码的正确性取决于操作系统。
  • 为什么递归地这样做?没有什么是常规迭代无法完成的。你没有返回任何值,你没有改变任何东西,你只是潜入 10,000 次然后退出,所以递归本质上是无用的。
  • @cad 好的,请告诉我这里出了什么问题,真的吗?我认为这是一个非常基本的代码,不涉及繁重的内容。
  • 堆栈溢出,我敢肯定。递归在 Windows 上炸毁了你的堆栈。显然你的 Linux 版本有更多的堆栈空间。
  • 我对你的程序做了一个快速修改,以确定递归的深度。它递归了 104741 次调用。好多啊。至少在 Windows 上可能是堆栈空间问题。在 Linux 上,这可能是一个问题,但可能不会表现为分段错误。补充@MarcB 的观点,使用递归不仅仅是品味问题。这是实现此算法的糟糕方法,可能会导致您遇到问题。

标签: c linux windows pointers codeblocks


【解决方案1】:

以下代码编译干净,产生预期输出,不使用递归,大大减少flag值抖动量,将计算算法与结果显示分开,在linux 14.04上测试

// 10001st prime
/*
 * By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13,
 * we can see that the 6th prime is 13.
 * What is the 10001st prime number?
 */

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

#define FIRST_NUM  (2)
#define START_COUNT (0)
#define WHICH_PRIME (10001)

int prime( void )
{
    int i;
    int num = FIRST_NUM;

    for( int count = 0; count < WHICH_PRIME; )
    {
        int flag=1;
        int j = (int)sqrt((double)(num));

        for(i=2; i<=j; i++)
        {
            if( !(num%i) )
            {
                flag=0;
                break;
            }
        }

        if(flag)
        {
            count++;

            if(count==10001)
                break;
        }

        num++;
    }
    return num;
}


int main(void)
{
    int result = prime();
    printf("The 10001st prime number is %d\n", result);
    return 0;
}

// Answer: 104743

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多