我正在使用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);
}
答案 0 :(得分:0)
multiply
函数中至少存在一个问题:
...
for (r = h3, k = 0; k < power; k++)
r = r->next;
r->coeff = r->coeff + coeff;
...
在某个时候,r
变成NULL
,并在下一步使用r
取消引用r->coeff
时(r
现在是NULL
)您的程序将导致未定义的行为(在大多数平台上为段错误)。
答案 1 :(得分:0)
有几个问题:
内存已泄漏:确保每个free
都指向一个malloc
。
read
正在创建一个新列表,但泄漏了该列表,并且从未更新过h1
或h2
中的数据。
add
未检查NULL 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] = '\0'; // 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;
}
答案 2 :(得分:-3)
我认为您应该在读取方法中使用内存复制
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))
}