为什么运行此代码时出现分段错误?

时间:2020-08-26 15:54:13

标签: c pointers gcc segmentation-fault

#include <stdio.h>

void avg_sum(double a[], int n, double *avg, double *sum)
{
    int i;
    sum = 0;
    printf("%f", *sum);
    for(i=0; i<n; i++)
        *sum += a[i];
    *avg = *sum/n;
}


int main()
{
    double arr[2] = {0.0,1.0};
    double *sum;
    double *avg;
    int n = 2;
    avg_sum(arr, n, avg, sum);
    printf("...Done...\n");
    
    return 0;
}

尝试使用GCC(https://www.tutorialspoint.com/compile_c_online.php)和clang(来自repl.it)在线编译器

2 个答案:

答案 0 :(得分:1)

容易。在第6行中,您为sum分配了0,但sum不是实际的总和,而是指向它的指针。尝试打印时,您将访问无效的内存。

编辑: 顺便说一句,如果您尝试使用-fanalyzer进行编译,则会收到警告和解释。 https://godbolt.org/z/W6ehh8

答案 1 :(得分:1)

double *sum;

这将创建一个指向double的指针,但是它具有任意值,因此没有指向专用内存。

此外,在被调用的函数中,将sum指针设置为零(空指针),然后尝试使用该指针取消对内存的引用-这是一个很大的非数字。

我也要警惕for(i=0; i<n-2; i++)求和数组中的值。它不会包含最后两个,因为n是两个,这意味着它不会累加其中的任何一个。

正确的方法是:

void avg_sum(double a[], int n, double *avg, double *sum) {
    int i;
    *sum = 0;               // set content, not pointer.
    for(i=0; i<n; i++)      // do all elements.
        *sum += *(a+i);
    *avg = *sum/n;
}

int main(void) {
    double arr[2] = {0.0,1.0};
    double sum;                  // ensure actual storage
    double avg;                  // and here
    int n = 2;
    avg_sum(arr, n, &avg, &sum); // then pass pointers to actual storage

    printf("Sum=%f, Avg=%f\n", sum, avg);
    
    return 0;
}

这给了您预期的结果,

Sum=1.000000, Avg=0.500000