归零后的段错误
Segmentation fault after returning zero
我们在这学期学习了使用 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)] = '[=10=]';
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
}
但是这段代码在返回 0 后导致分段错误,正如我在使用 gdb 后发现的那样,这让我完全困惑。作为 C 和编程的新手,这完全让我感到困惑。请帮忙。
这个声明
char table_title[] = " n | ";
声明 table_title
为 8 个字符的数组。当您将其他字符串追加到数组的末尾时,您将越界并具有 undefined behavior.
要么指定一个足够大的大小来容纳您需要的所有数据,要么使用完整的字符串正确初始化它。
table_title
您分配了一个字符串,因此 sizof(table_title)
将无法保存您传递的整个字符串,因此越界访问数组是未定义的行为,可能会导致崩溃。
为什么使用 table_title?没有必要。只需使用 printf.
printf ("sin series | sin library | cos series | cos library | tan series | tan library | ");
您已静态声明 table_title。 free() 用于释放动态分配的内存。那就去做吧。不会出现分段错误。
好的,那么你可以使用 printf as
printf (
"sin series | sin library | " \
"cos series | cos library | " \
"tan series | tan library | ");
没有换行。试试这个。 :)
我们在这学期学习了使用 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)] = '[=10=]';
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
}
但是这段代码在返回 0 后导致分段错误,正如我在使用 gdb 后发现的那样,这让我完全困惑。作为 C 和编程的新手,这完全让我感到困惑。请帮忙。
这个声明
char table_title[] = " n | ";
声明 table_title
为 8 个字符的数组。当您将其他字符串追加到数组的末尾时,您将越界并具有 undefined behavior.
要么指定一个足够大的大小来容纳您需要的所有数据,要么使用完整的字符串正确初始化它。
table_title
您分配了一个字符串,因此 sizof(table_title)
将无法保存您传递的整个字符串,因此越界访问数组是未定义的行为,可能会导致崩溃。
为什么使用 table_title?没有必要。只需使用 printf.
printf ("sin series | sin library | cos series | cos library | tan series | tan library | ");
您已静态声明 table_title。 free() 用于释放动态分配的内存。那就去做吧。不会出现分段错误。
好的,那么你可以使用 printf as
printf (
"sin series | sin library | " \
"cos series | cos library | " \
"tan series | tan library | ");
没有换行。试试这个。 :)