不能使用结构体指针作为多个函数的参数

标签 c function pointers struct

这是一个在图书馆中注册书籍的程序,其中包含标题、作者和价格。以及计算平均值、最高价格书籍等内容...当我使用 vector {struct livro Livros[1000] 时,它运行得很好]} 而不是指针 {struct livro *Livros}。 我使用指针为书籍列表动态分配内存,并且注册书籍的一切都运行良好。但是当我尝试计算平均值(它调用另一个函数到 main )时,程序崩溃并且编译器(我在学校使用 Visual Studio)显示该消息:

Livraria.exe 中 0x00ec174c 处未处理的异常:0xC0000005:读取位置 0xcccccd94 时发生访问冲突。

我尝试使用该函数按编写器而不是平均值进行定位,但在我放置字符串后它就崩溃了。当然,当它使用“Livros[i].autor”来比较字符串时

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

#define flush_toilet (fflush(stdin))
//mude o #define dependendo do seu SO
//__fpurge(stdin); "linux"
//fflush(stdin);    "windows"

struct livro {
char titulo [100];
char autor [100];
float prec;
};

//register
void cadastro (int *qtd, struct livro *Livros){
    int i;
    Livros=NULL;



printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
scanf ("%i",qtd);
flush_toilet;

Livros = malloc( *qtd *sizeof(struct livro));    //allocates the memory for the list

printf ("insira os dados de cada livro:");

    for (i=0;i<*qtd;i=i+1){
    printf ("\n\n\ninsira o titulo:"); 
    gets (Livros[i].titulo);      //title
    flush_toilet;

    printf ("\ninsira o nome:");
    gets (Livros[i].autor);      //writer
    flush_toilet;

    printf ("\ninsira o preco :");
    scanf ("%f",&Livros[i].prec);//price
    flush_toilet;
    }
}





//calculate average of prices
float media (int qtd, struct livro *Livros){
int i;
float  media=0;
    for (i=0;i<qtd;i=i+1){
    media=media+Livros[i].prec;
    }

media=media/qtd;
return media;

}


//calculate number of books above average
int qtd_acima_med (float media, struct livro *Livros, int qtd){
int acima=0,i;

    for (i=0;i<qtd;i=i+1){

        if(Livros[i].prec>media){
        acima=acima+1;
        }
    }

return acima;


}


//locate a book by writer
void localizar(int qtd, struct livro *Livros){
int i;
char autor[100];

printf("\ndigite o nome do autor cujos livros deseja encontrar:\n");
gets (autor);
flush_toilet;
printf("\n");

    for (i=0;i<qtd;i=i+1){

        if((strcmp (autor, Livros[i].autor))==0){
        puts(Livros[i].titulo);
        printf("\n");
        }


    }
}


//finds and displays the most expensive book
void mais_caro (int qtd, struct livro *Livros ){
int i, ncaro;
float caro=0;
    for (i=0;i<qtd;i=i+1){

        if (Livros [i].prec>caro){
        caro=Livros [i].prec;
        ncaro=i;
        }

    }

puts (Livros[ncaro].titulo);
printf ("preco:  %f\n", Livros[ncaro].prec);
}


void main (){
struct livro *Livros;

int qtd=-1, selec=1, nacima=-1;
float med=-1;

    while (selec!=0){
    printf ("\n\n\nDigite 0 para sair,\n 1 para cadastrar,\n 2 para calcular a media,\n 3 para calcular os livros acima da media,\n 4 para localizar o livro pelo autor,\n 5 para achar o mais caro.\n\n");
    scanf("%i", &selec);
flush_toilet;
        switch (selec){

            case 0:
            break;


            case 1:{
            cadastro(&qtd, Livros);
            break;
            }


            case 2:{

                if(qtd<0){
                printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
                break;
                }
            med=media(qtd, Livros);
            printf("A media e igual a: %f \n", med);

            break;
            }


            case 3:{

                if(med<0){
                printf("erro a media n foi calculada\n");
                break;
                }

            nacima = qtd_acima_med (med, Livros, qtd);
            printf("A qtd de livros com preco acima da media e: %i \n", nacima);
            break;
            }


            case 4:{
                if(qtd<0){
                printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
                break;
                }

            localizar(qtd, Livros);

            break;
            }


            case 5:{
                if(qtd<0){
                printf("erro nenhum livro cadastrado ou processo de cadastro incorreto\n");
                break;
                }

            mais_caro (qtd, Livros);

            break;
            }
        }

    }

free(Livros);
}

最佳答案

编译时出现以下错误:

1>main.c(138) : warning C4700: uninitialized local variable 'Livros' used

这似乎是该错误的原因。要修复此问题,您需要从 cadastro 返回分配的数组:

struct livro * cadastro (int *qtd){
    int i;
    struct livro *Livros =NULL;

    printf("Insira a quantidade de livros:");//defines the quantity(variable "qtd") of books which will pass to the main function(it worked when i used vectors)
    scanf ("%i",qtd);
    flush_toilet;

    Livros = malloc( *qtd * sizeof(struct livro));    //allocates the memory for the list

    printf ("insira os dados de cada livro:");

    for (i=0;i<*qtd;i=i+1){
        printf ("\n\n\ninsira o titulo:"); 
        gets (Livros[i].titulo);      //title
        flush_toilet;

        printf ("\ninsira o nome:");
        gets (Livros[i].autor);      //writer
        flush_toilet;

        printf ("\ninsira o preco :");
        scanf ("%f",&Livros[i].prec);//price
        flush_toilet;
    }

    return Livros;
}

然后在main()中使用return:

void main (){
    struct livro *Livros = NULL;

    int qtd=-1, selec=1, nacima=-1;
    float med=-1;

    while (selec!=0){

// Snip

        switch (selec){

// snip
            case 1:
                {
                    if (Livros != NULL)
                    {
                        free(Livros);
                        Livros = NULL;
                    }
                    Livros = cadastro(&qtd);
                }
                break;                  

您还需要检查 scanf()gets() 的返回值,以防没有更多输入或无效输入,并且有默认情况用户为 selec 输入无效值的事件。您还应该考虑替换 gets() with fgets()以防止缓冲区溢出。但崩溃的直接原因是未初始化的变量。想必您的编译器也会报告类似的警告,如果确实如此,则应始终修复此类警告。

关于不能使用结构体指针作为多个函数的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27434950/

相关文章:

c - 提取部分文件路径的简单方法?

function - “链接功能”和 'Activation function'

c++ - 使用类的 vector

c - C 中 mymethod(i) 和 mymethod(&i) 有什么区别?

c - C 中的 System() 函数显示有错误的输出

c - C语言中如何让用户输入的句子全部大写?

c++ - 传递常量引用...它是否像最重要的常量一样工作?

c++ - 使用 'this' 指针的链接函数

c - 求和给出随机错误数字

python - "Variable"未访问