简体   繁体   English

为什么此C程序会导致分段错误(内核已转储)?

[英]Why does this C program lead to a segmentation fault (core dumped)?

I've tried solving a math problem ( https://projecteuler.net/problem=2 ) in C but my program leads to a segmentation fault. 我曾尝试解决C语言中的数学问题( https://projecteuler.net/problem=2 ),但是我的程序会导致分段错误。 I've tried looking through the code, searching on this site as well as using -Wall and -Wpedantic to no avail. 我尝试浏览代码,在该站点上搜索以及使用-Wall和-Wpedantic均无济于事。 What exactly in this code is causing a segmentation fault (core dumped)? 这段代码中究竟是什么引起分段错误(核心转储)?

#include <stdio.h>
#include <stdlib.h>

// Calculates the sum of all fib numbers
// below (non-inclusive) the parameter num.
int calculate(int num) {
    int i = 2, bytes_to_allocate;

    // ---------- BEGIN: Memory Allocation Calculation ----------
    // Calculates the exact number of fibs less than num, and saves this
    // to the variable called "bytes_to_allocate".

    int flist[3]; // A small list of 3 ints to calculate fib numbers.

    flist[0] = 1;
    flist[1] = 2;

    // The if statements in this loop are used to move the
    // index i to the proper place in order to calculate
    // every fib number less than num.
    while(1) {
        if(i == 0) {
            if(flist[i+1] + flist[i+2] >= num) {
                break;
            }
            flist[i] = flist[i+1] + flist[i+2];
            i = 1;
        }
        else if(i == 1) {
            if(flist[i-1] + flist[i+1] >= num) {
                break;
            }
            flist[i] = flist[i-1] + flist[i+1];
            i = 2;
        }
        else if(i == 2) {
            if(flist[i-1] + flist[i-2] >= num) {
                break;
            }
            flist[i] = flist[i-1] + flist[i-2];
            i = 0;
        }
        bytes_to_allocate++;
    }

    // ---------- END: Memory Allocation Calculation ----------

    // Allocates exactly the right amount of bytes corresponding
    // to the number of fibs below value num.
    int* list = calloc(bytes_to_allocate, sizeof(int));

    if(list == NULL) {
        printf("Malloc failed.\n");
        exit(1);
    }

    list[0] = 1;
    list[1] = 2;

    // This loop initializes all fibs that are < num in list.
    for(i = 2; i < num; i++) {
        if(list[i-1] + list[i-2] < num) {
            list[i] = list[i-1] + list[i-2];
        }
        else { // If not less than num
            break;
        }
    }

    // Add all of the even fibs in the list (and the cleared adresses)
    int sum = 0;
    for(i = 0; i < num; i++) {
        if(list[i] % 2 == 0) {
            sum += list[i];
        }
    }

    free(list); // Frees up allocated memory.

    return sum;
}

int main(void) {
    int sum;
    int num = 4000000;
    sum = calculate(num);
    printf("\nSum of even-valued fibs < %d: %d\n\n", num, sum);
    return 0;
}

You're not allocating enough memory for list . 您没有为list分配足够的内存。 Just make it big enough to hold num numbers: 只是让它大到足以容纳num数字:

int* list = calloc(num, sizeof(int));

For issues like this, valgrind is your friend. 对于此类问题,valgrind是您的朋友。 When I ran your code through it, it said that initialization loop was writing past the end of the allocated memory. 当我在其中运行您的代码时,它表示初始化循环正在写入已分配内存的末尾。

EDIT: 编辑:

Doing this also saves you the time and code of counting the number of fibs beforehand, so everything in calculate before the allocation can go away. 这样做还节省了您预先calculate纤维数量的时间和代码,因此分配之前可以进行calculate所有内容都可以省去。

EDIT 2: 编辑2:

A much simpler way that doesn't require a large memory footprint: 一个不需要大量内存的简单方法:

int calculate(int num)
{
    int prev1, prev2, curr;
    int sum;

    sum = 0;
    prev1 = 0;
    prev2 = 1;
    curr = 1;

    while (curr < num) {
        if (curr % 2 == 0) {
            sum += curr;
        }
        prev1 = prev2;
        prev2 = curr;
        curr = prev1 + prev2;
    }
    return sum;
}

You are trying to bytes_to_allocate++ where bytes_to_allocate is uninitialized. 您正在尝试bytes_to_allocate++哪里bytes_to_allocate被初始化。

Initialize bytes_to_allocate++ first. 首先初始化bytes_to_allocate++

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM