我正在研究 c 编程代码,除了多项式乘法部分外,大多数代码都运行良好。它有一个运行时错误。请帮助我从多项式乘法中删除此运行时错误,我找不到我认为它在第三个 for 循环中的错误。 谢谢。。。 如果你解决错误会很棒
#include<math.h>
#include<stdio.h>
#include<stdlib.h>
#define MAX 17
typedef struct node
{
int coeff;
struct node *next;
}node;
node * init();
void read(node *h1);
void print(node *h1);
node * add(node *h1,node *h2);
node * multiply(node *h1, node *h2);
void main()
{
node *h1=NULL,*h2=NULL,*h3=NULL;
int option;
do
{
printf("n1 : create 1’st polynomial");
printf("n2 : create 2’nd polynomial");
printf("n3 : Add polynomials");
printf("n4 : Multiply polynomials");
printf("n5 : Quit");
printf("nEnter your choice :");
scanf("%d",&option);
switch(option)
{
case 1:
h1=init();
read(h1);
break;
case 2:
h2=init();
read(h2);
break;
case 3:
h3=add(h1,h2);
printf("n1’st polynomial -> ");
print(h1);
printf("n2’nd polynomial -> ");
print(h2);
printf("n Sum = ");
print(h3);
break;
case 4:
h3=multiply(h1,h2);
printf("n1’st polynomial -> ");
print(h1);
printf("n2’nd polynomial -> ");
print(h2);
printf("n Product = ");
print(h3);
break;
}
}while(option!=5);
}
void read(node *h)
{
int n,i,j,power,coeff;
node *p;
p=init();
printf("n Enter number of terms :");
scanf("%d",&n);
/* read n terms */
for (i=0;i<n;i++)
{
printf("nenter a term(power coeff.)");
scanf("%d%d",&power,&coeff);
for(p=h,j=0;j<power;j++)
p=p->next;
p->coeff=coeff;
}
}
void print(node *p)
{
int i;
for(i=0;p!=NULL;i++,p=p->next)
if(p->coeff!=0)
printf("%dX^%d ",p->coeff,i);
}
node * add(node *h1, node *h2)
{
node *h3,*p;
h3=init();
p=h3;
while(h1!=NULL)
{
h3->coeff=h1->coeff+h2->coeff;
h1=h1->next;
h2=h2->next;
h3=h3->next;
}
return(p);
}
node * multiply(node *h1, node *h2)
{
node *h3,*p,*q,*r;
int i,j,k,coeff,power;
h3=init();
for(p=h1,i=0;p!=NULL;p=p->next,i++)
for(q=h2,j=0;q!=NULL;q=q->next,j++)
{
coeff=p->coeff * q->coeff;
power=i+j;
for(r=h3,k=0;k<power;k++)
r=r->next;
r->coeff=r->coeff+coeff;
}
return(h3);
}
node * init()
{
int i;
node *h=NULL,*p;
for(i=0;i<MAX;i++)
{
p=(node*)malloc(sizeof(node));
p->next=h;
p->coeff=0;
h=p;
}
return(h);
}
multiply
函数中至少存在一个问题:
...
for (r = h3, k = 0; k < power; k++)
r = r->next;
r->coeff = r->coeff + coeff;
...
在某些时候,r
变得NULL
,在下一步中,当您取消引用r
时r->coeff
(r
现在正在NULL
(,您的程序将导致未定义的行为(大多数平台上的段错误(。
有几个问题:
-
内存泄露:确保您可以为每个
malloc
指出一个free
。 -
read
正在创建一个新列表,但泄露了它并且从未更新h1
或h2
中的数据。 -
add
没有检查空h2
。 -
不必要地保留了加法/乘法的结果。
最多有 17 个节点 - 链表的全部意义在于无需维护这种任意限制。
变量的作用域太大。这是 2011 年:可以在使用点附近而不是在块的开头声明变量。
scanf
的使用不是惯用的,不适用于交互式面向线路的输入。对于此类输入,读取完整的行并解析它们,而不是 stdin 流。在 stdin 流中,换行符是一个字段分隔符,我认为您不希望这样。没有任何断言:防御性地编程,断言你认为应该是真的。
这有效,并且在任何情况下都应该是正确的并且没有未定义的行为。
// https://github.com/KubaO/stackoverflown/tree/master/questions/c-linked-debug-52867729
#include <assert.h>
#include <math.h>
#include <stdarg.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct Node {
int power; // primary key for sorting
int coeff;
struct Node *next;
} Node;
Node *new_node(Node *prev, Node *next, int power);
Node *get_node(Node **head, Node *hint, int power);
void delete_nodes(Node *head);
Node *read(void);
void print(const Node *head);
Node *add(const Node *head1, const Node *head2);
Node *multiply(const Node *head1, const Node *head2);
void print_nodes(const Node *n1, const Node *n2, const char *extra_label,
const Node *extra);
const char *arity_suffix(int n);
bool parse_line(int max_length, const char *fmt, int count, ...);
static void *guarded_malloc(size_t size) {
void *result = malloc(size);
if (!result) {
fprintf(stdout, "Memory allocation has failed: exiting.");
abort();
}
return result;
}
int main() {
Node *h1 = NULL, *h2 = NULL;
int option;
do {
printf("n1 : Create 1'st polynomial");
printf("n2 : Create 2'nd polynomial");
printf("n3 : Print polynomials");
printf("n4 : Add polynomials");
printf("n5 : Multiply polynomials");
printf("n6 : Quit");
printf("nEnter your choice: ");
if (!parse_line(10, "%d", 1, &option)) continue;
switch (option) {
case 1:
delete_nodes(h1);
h1 = read();
break;
case 2:
delete_nodes(h2);
h2 = read();
break;
case 3:
print_nodes(h1, h2, NULL, NULL);
break;
case 4: {
Node *sum = add(h1, h2);
print_nodes(h1, h2, "Sum", sum);
delete_nodes(sum);
break;
}
case 5: {
Node *prod = multiply(h1, h2);
print_nodes(h1, h2, "Product", prod);
delete_nodes(prod);
break;
}
}
} while (option != 6);
delete_nodes(h1);
delete_nodes(h2);
}
Node *read() {
int n;
printf("n Enter number of terms: ");
if (!parse_line(10, "%d", 1, &n)) return NULL;
/* read n terms */
Node *head = NULL;
for (int i = 0; i < n;) {
int power, coeff;
printf("nEnter the %d%s term (power coeff): ", i + 1, arity_suffix(i + 1));
if (!parse_line(80, "%d%d", 2, &power, &coeff) || !coeff) continue;
Node *p = get_node(&head, NULL, power);
if (!p->coeff) i++; // count only new terms
p->coeff = coeff;
}
return head;
}
void print(const Node *p) {
for (; p; p = p->next) printf("%dX^%d ", p->coeff, p->power);
}
void add_to(Node **sum, const Node *h) {
Node *r = NULL;
for (; h; h = h->next) {
r = get_node(sum, r, h->power);
r->coeff += h->coeff;
}
}
Node *add(const Node *h1, const Node *h2) {
Node *sum = NULL;
add_to(&sum, h1);
add_to(&sum, h2);
return sum;
}
Node *multiply(const Node *h1, const Node *h2) {
Node *prod = NULL;
for (const Node *p = h1; p; p = p->next) {
Node *r = NULL;
for (const Node *q = h2; q; q = q->next) {
int power = p->power + q->power;
r = get_node(&prod, r, power);
r->coeff += p->coeff * q->coeff;
}
}
return prod;
}
Node *new_node(Node *prev, Node *next, int power) {
assert(!prev || prev->power < power);
assert(!next || next->power > power);
Node *node = guarded_malloc(sizeof(Node));
node->power = power;
node->coeff = 0;
node->next = next;
if (prev) prev->next = node;
return node;
}
void delete_nodes(Node *head) {
while (head) {
Node *p = head;
head = head->next;
free(p);
}
}
static bool list_contains(Node *head, Node *elt) {
for (; head; head = head->next)
if (head == elt) return true;
return false;
}
Node *get_node(Node **head, Node *hint, int power) {
Node *node = hint;
Node *next = hint ? hint->next : head ? *head : NULL;
assert(!hint || !*head || list_contains(*head, hint));
assert(!hint || hint->power <= power);
assert(!node || !next || node->power < next->power);
while (next && next->power <= power) {
node = next;
next = next->next;
}
if (!node || node->power != power) {
assert(!node || node->power < power);
Node *n = new_node(node, next, power);
if (!node) *head = n;
node = n;
}
return node;
}
void print_nodes(const Node *h1, const Node *h2, const char *extra_label,
const Node *extra) {
printf("n1'st polynomial -> ");
print(h1);
printf("n2'nd polynomial -> ");
print(h2);
if (extra_label) {
printf("n %s = ", extra_label);
print(extra);
}
printf("n");
}
const char *arity_suffix(int n) {
if (n == 0) return "st";
if (n == 1) return "nd";
return "rd";
}
bool parse_line(int max_length, const char *fmt, int count, ...) {
bool result = false;
int const buf_size = max_length + 2; // include n and zero termination
char *const buf = guarded_malloc((size_t)buf_size);
char *const str = fgets(buf, buf_size, stdin);
if (str) {
size_t n = strlen(str);
if (str[n - 1] == 'n') { // we must have read a whole line
str[n - 1] = ' '; // remove the newline
va_list ap;
va_start(ap, count);
int rc = vsscanf(buf, fmt, ap);
va_end(ap);
result = rc == count;
}
}
free(buf);
return result;
}
我认为你应该在读取方法中使用memcopy
。void read(node *h)
{
int n,i,j,power,coeff;
node *p;
p=init();
printf("n Enter number of terms :");
scanf("%d",&n);
/* read n terms */
for (i=0;i<n;i++)
{
printf("nenter a term(power coeff.)");
scanf("%d%d",&power,&coeff);
for(p=h,j=0;j<power;j++)
p=p->next;
p->coeff=coeff;
}
memcpy (h, p, sizeof(node))
}