Can't use struct pointers as parameters of mutiple functions - c

This is a program to register books in a library with title, writer and price.As well as calculate things such as averages, highest price book... It ran pretty well when i used a vector {struct livro Livros[1000]} instead of a pointer {struct livro *Livros}.
I used the pointers to dynamically allocate memory for the book list and everything runs fine registering the books. but when i try to calculate the average, which calls another function to main, the program crashes and the compiler(i use visual studio in my school) shows that message:
Unhandled exception at 0x00ec174c in Livraria.exe: 0xC0000005: Access violation reading location 0xcccccd94.
I tried to use the function to locate by writer instead of the average and it crashed just after i have put the string. Certainly when it used the "Livros[i].autor" to compare the strings
#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);
}

When I compile, I get the following error:
1>main.c(138) : warning C4700: uninitialized local variable 'Livros' used
This looks to be the cause of the bug. To fix, you need to return the allocated array from 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;
}
And then later use the return in main ():
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;
You also need to check the return values of scanf() and gets() in case there is no more input or invalid input, and have a default case in the event the user enters an invalid value for selec. You should also consider replacing gets() with fgets() to prevent buffer overruns. But the immediate cause of the crash is the uninitialized variable. Presumably your compiler also reports a similar warning, and if it does, warnings like this should always be fixed.

Related

Undefined reference to pesquisar_bin

//Ordenacao por insercao/selecao
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <ctype.h>
int vet[10]={8,16,34,13,19,7,45,3,12,9},a,b,aux;
void selecao();
int pesquisar_bin(int,int,int,int);
int main (){
int opt=0,num,max;
char continuar;
printf("ESCOLHA O METODO DE ORDENACAO:\n\
1- INSERCAO\n\
2- SELECAO\n\
3- SAIR\n");
do{
scanf("%d",&opt);
}while(opt!=1 && opt!=2 && opt!=3);
switch(opt){
case 1:
break;
case 2:
selecao();
break;
case 3:
exit(1);
break;
}
printf("\n\n1- PESQUISA SEQUENCIAL\n\n\
2- PESQUISA BINARIA\n");
do{
aux=0;
scanf("%d",&aux);
}while(aux!=1&&aux!=2);
printf("DIGITE O VALOR A SER PESQUISADO:\n");
scanf("%d",&num);
else if(aux==2){
max=sizeof(vet)/sizeof(int);
pesquisar_bin(vet[max],0,max,num);
}
}
//ORDENACAO POR SELECAO
void selecao(){
int i=1;
do{
b=0;
for (a=0;a<9;a++){
if(vet[a+1]<vet[a]){
aux=vet[a];
vet[a]=vet[a+1];
vet[a+1]=aux;
b=1;
}
}
if(b==1){
printf("Fase %d: [",i);
for(a=0;a<10;a++){
printf("%d ",vet[a]);
}
printf("]\n\n");
i++;
}
}while(b==1);
}
//PESQUISA BINARIA
int pesquisar_bin(int vetor[],int ini,int fim,int numero){
int pos;
pos=((fim-ini)/2)+ini;
if (ini>fim){
printf("Valor %d nao encontrado no vetor\n",numero);
return 0;
}
if(numero>vet[pos]){
return (pesquisar_bin(vet,pos+1,fim,numero));
}
else if(numero<vet[pos]){
return (pesquisar_bin(vet,ini,pos-1,numero));
}
else if(numero==vet[pos]){
printf("O valor %d se encontra na posicao %d do vetor.",numero,pos);
return 0;
}
}
I've been doing some exercises of C but I really don't understand why dev C++ is returning this error.
I already tried to do many things like to change the reference including a point and other things.
C:\Users\ANONYM~1\AppData\Local\Temp\ccguUdp9.o ordenacao.cpp:(.text+0x128):
undefined reference to `pesquisar_bin(int, int, int, int)'
\Mac\Home\Desktop\EXERCICIOS ED\collect2.exe [Error] ld returned 1
exit status
Your declaration and use of pesquisar_bin, does not match your implementation. As #JMichelB points out, vetor is declared to be an int and you pass it an int when calling pesquisar_bin, but your implementation defines vetor as an int[]. In the absence of an MCVE, that's the best we can surmise at this point in time.
Your implementation of pesquisar_bin is ignoring the vetor parameter and using the vet variable from file scope instead. The code is a mess due to your thrashing about and not actually posting an MCVE. Pass vet to pesquisar_bin and change the implementation to use the vetor parameter.

Doubly linked circular list

This code tries to implement a doubly linked circular list
The code compiles, does not throw error, but when entering a number is hung where is the fault? Pretend that the signs in Spanish are in English
#include <stdio.h>
#include <conio.h>
#include <windows.h>
#include <stdlib.h>
struct lista
{
int info;
struct lista *sig,*ant;
}*CAB=NULL,*AUX=NULL,*Q=NULL,*P=NULL,*F=NULL,*QD=NULL,*FD=NULL;
main menu
int main() {
void insertard(void);
void extraerd(void);
void visualizard(void);
void visualizari(void);
void eliminardespues();
void eliminarantes();
char opc;
do{
system("cls");
printf("___________________________________________________\n");
printf("_¡¡¡MENU DE LISTA CIRCULAR DOBLEMENTE ENLAZADA!!!__\n");
printf("___________________________________________________\n");
printf("____________SELECCIONE UNA OPCION__________________\n");
printf("___________________________________________________\n");
printf("___________________________________________________\n");
printf("__________1) INSERTAR______________________________\n");
printf("__________2) VISUALIZAR ASCENDIENTE________________\n");
printf("__________3) VISUALIZAR DESCENDIENTE_______________\n");
printf("__________4) INGRESAR Y ELIMINAR SIGUIENTE_________\n");
printf("__________5) INGRESAR Y ELIMINAR ANTERIOR__________\n");
printf("__________6) SALIR_________________________________\n");
printf("___________________________________________________\n");
opc=getch();
switch(opc)
{
case '1':
insertard();
break;
case '2':
visualizard();
break;
case '3':
visualizari();
break;
case '4':
eliminarantes();
break;
}
} while(opc!='6');
getch();
return 0;
}
Process insertard
void insertard(void)
{
P=CAB;
AUX=(struct lista *)malloc(sizeof(struct lista));
system("cls");
printf("INGRESE UN NUMERO ENTERO:");
scanf("%d",&AUX->info);
AUX->sig=CAB;
AUX->ant=CAB;
F=AUX;
if(CAB==NULL)
CAB=AUX;
}else{ //ESTO SI
while (P->sig!=CAB){
P=P->sig;
}
P->sig=AUX;
AUX->ant=P;
AUX->sig=CAB;
}
eliminardespues Process (Deletes an item after the list)
void eliminardespues(){
int x;
system("cls");
printf("INGRESE UN NUMERO PARA ELIMINAR EL SIGUIENTE:");
scanf("%d",&x);
FD=CAB;
QD=CAB;
while(FD->info!=x&&FD->sig!=CAB){
FD=FD->sig;
}QD=FD->sig;
if(FD->sig==CAB&&FD->info!=x){
printf("\nEL NUMERO INGRESADO NO SE ENCUENTA EN LA LISTA");
}else{
if(FD->info==x){
FD->sig=QD->sig;
(QD->sig)->ant=FD;
printf("\nELIMINADO %d",QD->info);
free(Q);
}
}
getch();
}
Process eliminarantes
void eliminarantes()
{
int x;
system("cls");
printf("INGRESE UN NUMERO PARA ELIMINAR EL ANTERIOR");
scanf("%d",&x);
FD=CAB;
QD=CAB;
while (FD->info!=x&&FD->sig!=CAB){
FD=FD->sig;
}QD=FD->ant;
if(FD->sig==CAB&&FD->info!=x){
printf("\nEL NUMERO INGRESADO NO SE ENCUENTA EN LA LISTA");
}else{
if(FD->info==x){
FD->ant=QD->ant;
(QD->ant)->sig=FD;
printf("\nELIMINADO %d",QD->info);
free(Q);
}
}
getch();
}
void visualizard(void)
{
system("cls");
if(CAB==NULL){
printf("LISTA VACIA");
getchar();
return;
}
AUX=CAB;
printf("LISTA:\n\n");
while(AUX->sig!=CAB){
printf("-> %d\n",AUX->info);
AUX=AUX->sig;
}
if(AUX->sig==CAB){
printf("-> %d\n",AUX->info);
}
getch();
}
void visualizari(void){
system("cls");
if(F==NULL){
printf("LISTA VACIA");
getchar();
return;
}
AUX=F;
printf("LISTA:\n\n");
do{
printf("-> %d\n",AUX->info);
AUX=AUX->ant;
}while(AUX->sig!=CAB);
getch();
}
In your first execution of method 'insertard' you are actually assigning P=CAB; i.e. P=NULL and in the blow line of code you are referring a null pointer to assign value.
P->sig=AUX;
I have modified your method which might fix it.
void insertard(void)
{
P=CAB;/* very first execution of this method P=NULL */
AUX=(struct lista *)malloc(sizeof(struct lista));
system("cls");
printf("INGRESE UN NUMERO ENTERO:");
scanf("%d",&AUX->info);
AUX->sig=CAB;
AUX->ant=CAB;
F=AUX;
if(CAB==NULL){
CAB=AUX;
P = AUX;/*first execution of this method P is no longer NULL but P is pointing to AUX */
}else{ //ESTO SI
while (P->sig!=CAB){
P=P->sig;
}
P->sig=AUX;
AUX->ant=P;
AUX->sig=CAB;
}

‘valor’ undeclared (first use in this function)

#include<stdio.h>
#include"push.c"
#include"pop.c"
#include"listadopila.c"
#include"structpila.c"
int main ()
{
struct pila valor;
void push();
int pop();
void listado();
int opcion=0;
valor.tope= -1;
int continuar;
printf ("=====ESTRUCTURA DE PILA=====\n\n");
do
{
printf ("Ingresa tu opcion:\n");
printf ("1) Para push\n");
printf ("2) Para pop\n");
printf ("3) Para mostrar tu pila\n");
printf ("4) Para salir.\n");
printf ("\n");
printf ("Ingresa tu opci%cn\n",163);
scanf("%d", &opcion);
switch(opcion)
{
case 1:
push(valor);
break;
case 2:
pop(valor);
break;
case 3:
listado(valor);
break;
default:
printf("Opción no válida.\n");
}
printf("\n¿Desea continuar comprando? Pulse cualquier tecla para si y N para no: ");
getchar();
scanf("%d",&continuar);
continuar=getchar();
}
while(continuar!='n'&&continuar!='N');
}
In other file, I define the struct like this:
struct pila
{
int pila[5];
int tope;
}valor;
And my functions are like this:
int pop()
{
int numero;
if (valor.tope==- 1)
{
printf ("La pila esta vacia.\n");
return (valor.tope);
}
else
{
numero=valor.pila[valor.tope];
printf("El elemento que haz eliminado es= %d", valor.pila[valor.tope]);
valor.tope=valor.tope -1;
}
return(numero);
}
I've tried changing the struct inside and outside the main and to write the functions into the switch case like: pop(valor); but it doesn't work either. Also in the files of each function I've tried to write the function like "int pop(struct pila valor)" but the compiler says I need to add a lenght for valor, the problem is that when I did the code in the same file the compilation finished succesfully, so the problem is when I try to link the struct with the other functions.
Any help?

How can I solve the segmentation fault (core dumped)?

I have this code and I don't know why after, I ask if you want to introduce another student and I say 1 or 0 the program ends and said segmentation fault (core dumped).
I ask to introduce another student in _nodo *insertaEnLista
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct actividades
{
char tipoDeActividad[22];
char diaDeLaSemana[12];
char horaDeIncio[8];
char horaDeFin[8];
};
struct materias
{
char nombre[30];
char profesor[30];
char tipoDeMateria[20];
struct actividades *actividad;
};
struct alumnos
{
char nombre[30];
int cedula;
int telefono;
struct materias *materia;
struct alumnos *siguiente;
};
typedef struct alumnos _nodo;
_nodo *crearLista(_nodo *apuntador);
bool listaVacia(_nodo *apuntador);
_nodo *insetarEnLista(char nombre[], long cedula, long telefono, _nodo *apuntador);
void imprimirLista (_nodo *apuntador);
_nodo *crearNodo(char nombre[], long int cedula, long int telefono);
//AQUI SE CREA LISTA Y SE PONE PARA QUE APUNTE A NULL
_nodo *crearLista(_nodo *apuntador)
{
return (apuntador = NULL);
}
//ESTA FUNCION VERIFICA SI LA LISTA ESTA VACIA
bool listaVacia(_nodo *apuntador)
{
if (apuntador == NULL)
return (true);
else
return (false);
}
//AQUI SE CREA EL NUEVO NODO DE LA LISTA
_nodo *crearNodo(char nombre[], long cedula, long telefono)
{
_nodo *registroNuevo;
registroNuevo = (_nodo *) malloc(sizeof(_nodo));
printf("\n----NUEVO ELEMENTO----\n");
printf("NOMBRE: ");
fflush(stdin);
scanf("%s",nombre);
printf("CEDULA: ");
fflush(stdin);
scanf("%ld", &cedula);
printf("TELEFONO: ");
fflush(stdin);
scanf("%ld", &telefono);
fflush(stdin);
strcpy(registroNuevo->nombre, nombre);
registroNuevo->cedula = cedula;
registroNuevo->telefono = telefono;
registroNuevo->siguiente = NULL;
return registroNuevo;
}
//AQUI SE INSERTA EL NODO EN LA LISTA LUGEO DE SER CREADO POR LA FUNCION crearNodo
_nodo *insetarEnLista(char nombre[], long cedula, long telefono, _nodo *apuntador)
{
_nodo *registroNuevo, *apuntadorAuxiliar;
char respuesta,ch;
do
{
registroNuevo=crearNodo(nombre, cedula, telefono);
if (listaVacia(apuntador)) apuntador = registroNuevo;
else
{
apuntadorAuxiliar = apuntador;
while (apuntadorAuxiliar->siguiente != NULL)
apuntadorAuxiliar = apuntadorAuxiliar->siguiente;
apuntadorAuxiliar->siguiente = registroNuevo;
}
printf("\nPARA INGRESAR A OTRO ALUMNO MARQUE... 1");
printf("\nPARA SALIR MARQUE... '0'\n");
while((ch = getchar()) != EOF && ch != '\n');
scanf("%c", &respuesta);
fflush(stdin);
printf("RESPUESTA = %c", respuesta);
}while (strcmp(&respuesta, "1")==0);
return apuntador;
}
//IMPRIMIR LOS NODOS DE LA LISTA
void imprimirLista (_nodo *apuntador)
{
_nodo *apuntadorAuxiliar;
apuntadorAuxiliar = apuntador;
if (apuntador == NULL)
printf("NO HAY ELEMENTOS EN LA LISTA \n");
else
{
while(apuntador != NULL)
{
printf(" \n------------NODO-------------- ");
printf("\nNOMBRE: %s \n\n", apuntadorAuxiliar->nombre);
printf("\n\nCEDULA: %d \n", apuntadorAuxiliar->cedula);
printf("\nTELEFONO: %d \n", apuntadorAuxiliar->telefono);
apuntadorAuxiliar = apuntadorAuxiliar->siguiente;
}
}
return;
}
int main()
{
/*printf("INTRODUZCA LOS NUMEROS DE CEDULA QUE DESEA IMPRIMIR \n");*/
_nodo *inicioLista;
int cedula;
int telefono;
char nombre[20];
inicioLista = crearLista(inicioLista);
inicioLista = insetarEnLista(nombre, cedula, telefono, inicioLista);
imprimirLista(inicioLista);
return 0;
}
How can I do to fix the problem.
You should step through the code in a debugger and look at the variables at each step to determine the line of code that is causing the issue.
Here is one issue, there may be others.
In this line
}while (strcmp(&respuesta, "1")==0);
you are using strcmp with a variable (respuesta) that contains a single character. strcmp is expecting a null terminated string (an array of characters with a zero byte at the end). As you may not have a zero byte after the variable, this may cause strcmp to read memory that it shouldn't (this is a buffer overrun)
Much simpler to just use:
}while (respuesta == '1');

C program gets an invalid conversion in a function

I have few error commented after this text, i don't get what the compiler is trying to say me, the last function is in to do list i hope that's not the problem, the problem is i want to ask the user for 2 chars after that its send to a function who will compare the strings as a password and a login if the strings are the same, the program continues.
\\initializing argument 1 of int consultar(char, char)\\
\\invalid conversion from char*' to `char' \\
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
void introducir_datos (struct agenda cliente[30]);
void mostrar_datos(struct agenda cliente[30]);
char consultar(char login,char password);
struct agenda{
char nombre[10];
char apellido[10];
int edad;
char direccion[20];
int codigo_postal;
};
int main(void)
{
struct agenda cliente[30];
int menu;
char con[3],login[8], password[8];
puts("\n=== Hola bienvenido a nuestra agenda en C ===\n");
puts("Login:");
gets(login);
puts("Password:");
gets(password);
**consultar(login, password);**
while ( menu != 3){
puts("\nQue quieres hacer?\n");
puts("[1]Insertar datos\n[2]Mostrar datos\n[3]Salir del programa\n");
scanf("%d", &menu);
switch(menu){
case 1:
introducir_datos(cliente);
break;
case 2:
mostrar_datos(cliente);
break;
default:
system("cls");
puts("~~~ Opcion incorrecta ~~~");
}
}
}
void introducir_datos (struct agenda cliente[30]){
int x = 0;
puts("\n=== Bienvenido a la introduccion de datos ===\n");
fflush(stdin);
system("pause");
system("cls");
puts("\nDime el nombre:\n");
fflush(stdin);
gets(cliente[x].nombre);
puts("\nDime el apellido:\n");
fflush(stdin);
gets(cliente[x].apellido);
puts("\nDime la edad:\n");
fflush(stdin);
scanf("%d",&cliente[x].edad);
puts("\nDime la direccion:\n");
fflush(stdin);
gets(cliente[x].direccion);
puts("\nDime el codigo postal:\n");
fflush(stdin);
scanf("%d",&cliente[x].codigo_postal);
x++;
}
void mostrar_datos(struct agenda cliente[30]){
for(int i=0;i<20;i++){
int x = 0;
printf("El nombre: %s \nEl apellido: %s\nEl edad: %d\nEl direccion: %s\nEl codigo postal: %d\n", cliente[x].nombre,cliente[x].apellido,cliente[x].edad,cliente[x].direccion,cliente[x].codigo_postal);
}
}
int consultar(char login, char password){
}
You need to change the consultar function (definition and implementation):
int consultar(char login, char password)
to:
int consultar(char *login, char *password)
If you use (char login, char password), it's looking for a single character. Since, by calling it with consultar(login, password);, you're using pointers to char arrays (simplified explaination), you're getting the error.
EDIT As pointed out by user "Namfuak", you should decide whether the function returns a char or an int, and have both definition and implementation be consistent.

Resources