得到一个“答案”;EXC“不良访问”;错误,我不知道为什么

得到一个“答案”;EXC“不良访问”;错误,我不知道为什么,c,runtime-error,C,Runtime Error,这是我的密码。它编译得很好,我根本看不出会出什么问题: // This program takes a quadratic from the user, and prints the solution(s) if they exist. #include <stdio.h> #include <stdlib.h> #include <math.h> #include <complex.h> //Make sign function

这是我的密码。它编译得很好,我根本看不出会出什么问题:

    // This program takes a quadratic from the user, and prints the solution(s) if they exist. 

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


//Make sign function for switch test - because in the switch expression itself, C refused to believe x/|x| is an integer...
int sign(float f){
    printf("\n\nSIGN CALL OK\n\n");
    int sign=f/cabs(f);
    return sign;
}

// Define quadratic structure 
typedef struct quadratic{
    float a, b, c;
    float discriminant;
    float real_root_1;
    float real_root_2;
    float complex_root;
} Quadratic;

// 'Redefine' malloc to also check allocation of memory when called.

Quadratic* xmalloc(size_t n){
    printf("\n\nXMALLOC CALL OK\n\n");
    Quadratic* p = malloc(n);
    if (p == NULL) {
        printf("\n ERROR: Unable to allocate memory! \n");
        exit(1);
    }
    return p;
}

// newquadratic lets the user define the quadratic to be solved, and returns the pointer to its structure. 

Quadratic* newquadratic() {
    Quadratic* q = xmalloc(sizeof *q);
    printf("\n Please enter the coefficients of the quadratic separated by spaces: ");
    scanf("%g, %g, %g", q->a, q->b, q->c);
    printf("\n\nDATA ACCEPTED\n\n");
    return q;
}

// solve takes the existing data from the quadratics structure and defines the remaining quantities, depending on which
// case we get for the 'sign of the discriminant'.

int solve(Quadratic eqn){
    printf("\n\nSOLVE CALL OK\n\n");
    eqn.discriminant = (eqn.b*eqn.b - 4*eqn.a*eqn.c);

    switch (sign(eqn.discriminant)) {
        case -1:
            eqn.real_root_1 = (-eqn.b+sqrt(eqn.discriminant))/(2*eqn.a);
            eqn.real_root_2 = (-eqn.b-sqrt(eqn.discriminant))/(2*eqn.a);
            break;
        case 0:
            eqn.real_root_1 = (-eqn.b+sqrt(eqn.discriminant))/(2*eqn.a);
            break;
        case 1:
            eqn.complex_root = (-eqn.b+sqrt(eqn.discriminant))/(2*eqn.a);
            break;
    }
    return sign(eqn.discriminant);
}

//main also uses sign of the discriminant (as returned by solve) to decide how to behave appropriately for the case it receives.

int main () {

    Quadratic* eqn=newquadratic();

    printf("\n\n GET QUADRATIC OK\n\n");

    switch (solve(*eqn)) {
        case -1:
            printf("\n\n We have two real solutions, %g and %g", eqn->real_root_1, eqn->real_root_2);
            break;
        case 0:
            printf("\n\n We have one repeated real solution, %g", eqn->real_root_1);
            break;
        case 1:
            printf("\n\n We have two complex solutions, %g%+gi and %g%-gi", creal(eqn->complex_root),cimag(eqn->complex_root),creal(eqn->complex_root),(-1)*cimag(eqn->complex_root));
            break;
    }

        return 0;
}
//此程序从用户处获取一个二次型,并打印解决方案(如果存在)。
#包括
#包括
#包括
#包括
//为开关测试生成符号函数-因为在开关表达式本身中,C拒绝相信x/| x |是整数。。。
整数符号(浮点f){
printf(“\n\nSIGN CALL OK\n\n”);
内部标志=f/驾驶室(f);
返回标志;
}
//定义二次结构
类型定义结构二次型{
浮子a、b、c;
浮动判别式;
浮点实数_根_1;
浮点实数_根_2;
浮根;
}二次型;
//“重定义”malloc以在调用时也检查内存分配。
二次*xmalloc(尺寸){
printf(“\n\nXMALLOC CALL OK\n\n”);
二次*p=malloc(n);
if(p==NULL){
printf(“\n错误:无法分配内存!\n”);
出口(1);
}
返回p;
}
//newsquared允许用户定义要求解的二次型,并返回指向其结构的指针。
二次*newquadratic(){
二次*q=xmalloc(sizeof*q);
printf(“\n请输入用空格分隔的二次型的系数:”);
scanf(“%g,%g,%g”,q->a,q->b,q->c);
printf(“\n\n数据已接受\n\n”);
返回q;
}
//solve从二次结构中获取现有数据并定义剩余量,具体取决于
//我们得到的案例是“歧视符号”。
整数求解(二次方程){
printf(“\n\n保存调用确定\n\n”);
等式判别式=(等式b*等式b-4*等式a*等式c);
开关(符号(等式判别式)){
案例1:
eqn.real_root_1=(-eqn.b+sqrt(eqn.discriminant))/(2*eqn.a);
eqn.real_root_2=(-eqn.b-sqrt(eqn.discriminant))/(2*eqn.a);
打破
案例0:
eqn.real_root_1=(-eqn.b+sqrt(eqn.discriminant))/(2*eqn.a);
打破
案例1:
eqn.complex_根=(-eqn.b+sqrt(eqn.discriminant))/(2*eqn.a);
打破
}
返回符号(等式判别式);
}
//main还使用判别式的符号(由solve返回)来决定如何针对接收到的案例进行适当的操作。
int main(){
二次*eqn=newquadratic();
printf(“\n\n获得二次确定\n\n”);
开关(求解(*eqn)){
案例1:
printf(“\n\n我们有两个实解,%g和%g”,eqn->real\u root\u 1,eqn->real\u root\u 2);
打破
案例0:
printf(“\n\n我们有一个重复的实解,%g”,等式->实根1);
打破
案例1:
printf(“\n\n我们有两个复杂的解决方案,%g%+gi和%g%%gi”,creal(eqn->complex_根),cimag(eqn->complex_根),creal(eqn->complex_根),(-1)*cimag(eqn->complex_根);
打破
}
返回0;
}

xmalloc调用正确,我们进入了用户输入3个系数的阶段。一旦按下回车键,我们就会得到错误

问题出在函数中

scanf函数期望得到它应该将结果放入的变量的地址,而实际上您已经将变量所包含的值传递给了它

要修复,请按如下方式传递a、b和c的地址:(添加
&
字符)


是否验证了xmalloc正在分配的内存块的大小?否。。我甚至不知道我将如何做到这一点,或者如果这是一个问题,我需要做什么!第一门课我才上了8个星期,你可以先打印n的值,然后把它传递给malloc;这至少可以告诉你你想要的尺码。这是我一直与malloc在一起的一个问题,我认为这不算太糟糕。。但该行的读数为二次*q=malloc(sizeof*q);所以我给malloc提供了一个二次结构的大小,我当时也在声明。。在独立声明之前,我不知道sizeof对*q到底有什么意义。我将试着看看我是否能从中得到有用的信息;printf(“\n二次结构的大小%lu”,p的大小);二次q=xmalloc(sizeof*q);printf(“\n由malloc%lu分配的内存”,大小*q);说我的结构有28号,malloc也分配了*q28。,谢谢,这已经排序好了。出于某种原因,我认为q->a是q中指向a的指针…:咧嘴笑:不客气。这很容易做到。尤其是对这门课如此陌生的时候。语法可能会一次又一次地砸你的脑袋,直到有一天,它只是咔哒一声。
Quadratic* newquadratic() 
{
    Quadratic* q = xmalloc(sizeof *q);
    printf("\n Please enter the coefficients of the quadratic separated by spaces: ");
    scanf("%g, %g, %g", &q->a, &q->b, &q->c);
    printf("\n\nDATA ACCEPTED\n\n");
    return q;
}