返回零后的分段错误

时间:2015-01-23 11:06:09

标签: c segmentation-fault

在本学期我们正在使用C语言进行编程,在我们的第一个作业中,我们被要求使用手动和库实现来打印sin(x),cos(x)和tan(x)的值列表。所以,我写了下面的代码:

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

#define START   0
#define STOP    360
#define STEP    10

#define PI      3.14159265358979323846  /*For conversion: degrees <-> radians */

double rad(double x);   /* Converts angle in degrees to radians */
double next_term(double angle, int term_index);

/* Function prototypes for manual implementation of sin(x), cos(x) and tan(x) */
double sin_series(double x);
double cos_series(double x);
double tan_series(double x);


int main() {

    /* Creating and printing the table title:
    ** ==================================================================== */

    char table_title[] = "   n | ";
    strcat(table_title, "sin series | sin library | ");
    strcat(table_title, "cos series | cos library | ");
    strcat(table_title, "tan series | tan library | ");

    printf("%s \n", table_title);

    /* ==================================================================== */



    /* Creating and printing the line between the title and the table:
    ** ==================================================================== */

    char* second_line = (char*)malloc((strlen(table_title) + 1) * sizeof(char));

    for (int i = 0; i < strlen(table_title) - 1; i++) {
        second_line[i] = '=';
    }

    second_line[strlen(table_title)] = '\0';

    printf("%s \n", second_line);

    /* ==================================================================== */

    free(second_line);

    /* Creating each line of the table and printing it:
    ** ==================================================================== */

    for (int angle = 0; angle < 360; angle += 10) {

        printf("%4i | ", angle);
        printf("%10.5f | %11.5f | ",sin_series(angle), sin(rad(angle)) );
        printf("%10.5f | %11.5f | ",cos_series(angle), cos(rad(angle)) );
        printf("%10.5f | %11.5f | ",tan_series(angle), tan(rad(angle)) );
        printf("\n");
    }

    return 0;   
}

double rad(double x) {
    return ((PI * x) / 180);
}

double next_series_term(double angle, int term_index) {
    double result = 1.0;

    for (int i = 0; i < term_index; i++) {
        result *= angle;
        result /= (i + 1);
    }

    return result;
}

unsigned long long factorial(int x) {

    unsigned long long result = 1;

    for (int i = 0; i < x; i++) {
        result *= (i + 1);
    }

    return result;
}

double sin_series(double x) {

    double result = 0;

    if (x == 0 || x == 180 || x == 360) {
        result = 0;
    }
    else {
        for (int i = 0; i < 100; i++) {

        /* Calculating the next term to add to result to increase precision.*/

        double next_term = next_series_term(rad(x), 2*i + 1);
        next_term *= pow(-1,i);


        result += next_term; 
        }
    }


    return result;  
}

double cos_series(double x) {

    double result = 0;

    if (x == 90 || x == 270) {
        result = 0;
    }
    else {
        for (int i = 0; i < 100; i++) {

        /* Calculating the next term to add to result to increase precision.*/

        double next_term = next_series_term(rad(x), 2*i);
        next_term *= pow(-1,i);     

        result += next_term; 
        }

    }

    return result;  
}

double tan_series(double x) {
        return sin_series(x)/cos_series(x); //non-portable! searching for
                                            // better solution
}   

但是这个代码在使用gdb后发现返回0后会导致Segmentation故障并让我完全感到困惑。作为C和编程的新手,这让我感到困惑。请帮忙。

4 个答案:

答案 0 :(得分:4)

此声明

char table_title[] = "   n | ";

声明table_title八个字符的数组。当您将其他字符串附加到数组的末尾时,您将写出越界并拥有undefined behavior

指定一个足够大的大小来容纳您需要的所有数据,或者用完整的字符串正确初始化它。

答案 1 :(得分:1)

table_title你分配了一个字符串,所以sizof(table_title)将无法保存你传递的整个字符串,因此访问数组越界是未定义的行为,可能会导致崩溃。

答案 2 :(得分:1)

你为什么使用table_title?没有必要。只需使用printf。

printf ("sin series | sin library | cos series | cos library | tan series | tan library | ");

您静态声明了table_title。 free()用于释放动态分配的内存。这样做吧。不会出现分段错误。

答案 3 :(得分:1)

好的,你可以使用printf作为

printf (
    "sin series | sin library | " \
    "cos series | cos library | " \
    "tan series | tan library | ");

没有包装。试试这个。 :)