can i use -> in c? that bring me an error - c

i wrote this code for the university its an exercise to practice lists and sublists and i can't run it.
#include <stdio.h>
#include <stdlib.h>
typedef struct nodito{
int dato;
struct nodito *sig;}nodito;
typedef struct nodito * Sublista;
typedef struct nodo{
char nombre[10];
Sublista sub;
struct nodo *sig;}nodo;
typedef struct nodo *TLista;
void cargoL(TLista *L){
FILE *arch;
TLista nuevo,ant,act;
Sublista nuevito;
arch=fopen("texto.txt","rt");
if (arch==NULL){
printf("archivo no existe \n");
}
else{
while(!feof(arch)){
nuevo=(TLista)malloc(sizeof(nodo));
fscanf(arch,"%s %d",(nuevo->nombre),& (nuevo->sub->dato));
if ( *L==NULL || strcmp((*L)->nombre,nuevo->nombre)>0){
nuevo->sig=*L;
*L=nuevo;
nuevo->sub->sig=NULL;
}
else{
ant=NULL;
act=*L;
while ( act!=NULL && strcmp(act->nombre,nuevo->nombre)<=0){
ant=act;
act=act->sig;
}
if (act!=NULL && strcmp(act->nombre,nuevo->nombre)==0){
nuevito=(Sublista)malloc(sizeof(nodito));
nuevito->dato=nuevo->sub->dato;
free(nuevo);
nuevito->sig=act->sub;
act->sub=nuevito;
}
else{
ant->sig=nuevo;
nuevo->sig=act;
}
}
}
}
fclose(arch);
}
the line nuevo->sub->sig=NULL bring me an error
same for fscanf(arch,"%s %d",(nuevo->nombre),& (nuevo->sub->dato))
can i use the double ->?
is that the problem?
can anybody help me?

You allocated memory for nuevo using malloc, but you never allocated memory for sub inside nuevo.
You tried dereferencing it in fscanf and the statement where you set it to NULL.
A simple fix would be to allocate space for sub as
nuevo->sub = malloc(sizeof(*Sublista));
Both your errors should disappear now.
Do remember to free sub before you free nuevo.

Related

problem in creating binary search tree in c language

This code creates a binary search tree but it
runs sometimes normally and sometimes makes errors, even without changing anything in the code.
I can't get why this happening, what's the mistake ?
Even I changed the function that I used to create the tree from recursive to iterative but the same results.
#include <stdio.h>
#include <stdlib.h>
typedef struct sommet{
struct sommet * fg;
int val;
struct sommet * fd;
}sommet;
typedef sommet* ptrm;
ptrm creearbre(ptrm arbre,int ele);
void impression(ptrm arbre);
ptrm creearbre_rec(ptrm arbre,int ele);
int main()
{
ptrm arbre=NULL;
int tarbre,n;
printf("entre la taille de l'arbre:");
scanf("%d",&tarbre);
for(int i=0;i<tarbre;i++)
{
printf("entre l'element %d: ",i+1);
scanf("%d",&n);
arbre=creearbre_rec(arbre,n);
}
impression(arbre);
return 0;
}
ptrm creearbre_rec(ptrm arbre,int ele)
{
if(arbre==NULL)
{
arbre=malloc(sizeof arbre);
arbre->val=ele;
arbre->fd=NULL;
arbre->fg=NULL;
}
else if(arbre->val > ele)
arbre->fg=creearbre_rec(arbre->fg,ele);
else
arbre->fd=creearbre_rec(arbre->fd,ele);
return arbre;
}
void impression(ptrm arbre){
if(arbre != NULL){
printf(" %d -->", arbre->val);
impression(arbre->fg);
impression(arbre->fd);
}
}
ptrm creearbre(ptrm arbre,int ele){
ptrm p,q=arbre,r=NULL;
p=malloc(sizeof arbre);
p->val=ele;
p->fd=NULL;
p->fg=NULL;
if(arbre==NULL){
arbre=p;
}
else{
while(q!=NULL){
r=q;
if(ele > q->val)
q=q->fd;
else
q=q->fg;
}
if(ele > r->val)
r->fd=p;
else
r->fg=p;
}
return arbre;
}
The program has undefined behavior due to using an invalid size in the allocation of memory in statements
arbre=malloc(sizeof arbre);
and
p=malloc(sizeof arbre);
There are allocated memory for pointers instead of objects of the structure type.
You need to write
arbre=malloc(sizeof *arbre);
p=malloc(sizeof *arbre);

C program to add 2 polynomials and then displaying it

I am writing a C program to add 2 polynomials given by user then displaying it in a separate function but it is not adding anything. In fact, it is not giving any type of error message so I am very confused. I think the mistake can be in 'addpoly' function or display function. I don't know what I am doing wrong. Any type of help will be appreciated.
#include<stdio.h>
#include<stdlib.h>
#define MAX 3
struct polynomial
{
int coeff;
int exp;
struct polynomial *next;
};
typedef struct polynomial polynomial;
polynomial *p1=NULL,*p2=NULL,*p3=NULL, *head_address=NULL;
polynomial* create()
{
polynomial *head_address=NULL, *prev_address=NULL, *new_address=NULL;
int i;
for(i=0;i<MAX;i++)
{
new_address=(polynomial*)malloc(sizeof(polynomial));
printf("Enter coeff:\n");
scanf("%d",&new_address->coeff);
printf("Enter exp:\n");
scanf("%d",&new_address->exp );
new_address->next=0;
if(head_address==NULL){
head_address=prev_address=new_address;
}
else{
prev_address->next=new_address;
prev_address=new_address;
}}
return head_address; }
void polyadd(polynomial *p1, polynomial *p2,polynomial *p3)
{
//polynomial* p3=NULL;
while(p1->next!=NULL && p2->next!=NULL){
if(p1->exp > p2->exp){
p3->coeff=p1->coeff;
p3->exp=p1->exp;
p1=p1->next;
}
else if(p1->exp < p2->exp){
p3->coeff=p2->coeff;
p3->exp=p2->exp;
p2=p2->next;
}
else if(p1->exp==p2->exp){
p3->coeff=p1->coeff + p2->coeff;
p3->exp=p1->exp;
p1=p1->next;
p2=p2->next;
}
p3->next=(polynomial*)malloc(sizeof(polynomial));
p3=p3->next;
p3->next=NULL; }
while(p1->next || p2->next){
if(p1->next){
p3->exp=p1->exp;
p3->coeff=p1->coeff;
p1=p1->next;
}
else if(p2->next){
p3->exp=p2->exp;
p3->coeff=p2->coeff;
p2=p2->next;
}
p3->next=(polynomial*)malloc(sizeof(polynomial));
p3=p3->next;
p3->next=NULL;
}
}
void display(polynomial *temp){
polynomial *p3;
p3=temp;
temp=head_address;
while(temp->next!=NULL)
printf("%dx^%d",temp->coeff,temp->exp);
temp=temp->next;
if(temp->next!=NULL){
printf(" + ");
}
}
int main(){
polynomial *p1,*p2,*p3;
p1=create();
printf("Next:\n");
p2=create();
polyadd(p1,p2,p3);
printf("Result:\n");
display(p3);
return 0;
}
Your issue looks like a memory reference error. In your polyadd() function you're not mallocing as much as you need to. Your base p3 pointer for your linked list is still unallocated when you start referencing off it in your first while loop. To fix your memory issue you'll want to malloc p3 before using it and then make sure the subsequent ->next instances all get malloced before being used.
I don't think this is causing you issues currently but you also have global variables defined at the top and then defined again in main(). The local variables will be the only ones used as long as they're present but I would delete your globals and make sure you don't have unused duplicates to avoid confusion.

C function that creates a linked list with "divisible by 3" numbers from another linked list

First, I need to create and show a list that ends with number 1000. That works well.
Then, I want to create another list with only the numbers that are divisible by 3 in the first list, but it doesn't work.
The worst thing is that it doesn't even tell me what's going on. It just gives error in the execution but the console doesn't say anything.
I will really appreciate any help.
I tried all.
#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#define CANTIDAD_NUMEROS 13
#define CANTIDAD_NUMEROS2 6
#define DESDE 1
#define HASTA 10
typedef struct lista{
int num;
struct lista *sig;
}nodo;
void crear (nodo *pt, int, int);
void crear2 (nodo *pt, int, nodo *pt2);
void mostrar(nodo *pt);
int main()
{
int i=0;
int t=0;
nodo *prin;
nodo *prin2;
prin=(nodo*)malloc(sizeof(nodo));
prin2=(nodo*)malloc(sizeof(nodo));
crear(prin,i, t); //creates first list
mostrar (prin); //shows first list
crear2(prin,i, prin2); //gets 'divisible by 3' numbers
mostrar(prin2); // shows second list
return 0;
}
//creates list
void crear (nodo *registro, int cont, int t)
{
scanf("%d", &t);
registro->num = t;
if (registro->num == 1000)
registro->sig=NULL;
else
{
registro->sig=(nodo*)malloc(sizeof(nodo));
cont++;
crear (registro->sig,cont, t);
}
return;
}
//shows list
void mostrar (nodo *registro)
{
if (registro->sig !=NULL)
{
printf ("%d\n",registro->num);
mostrar (registro->sig);
}else{
printf("%d\n",registro->num);
}
return;
}
//creates second list with only numbers that are divisible by 3
void crear2 (nodo *registro, int cont, nodo *registroNuevo)
{
if ((registro->num % 3) == 0){
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
}
if(registro->sig != NULL){
crear2(registro->sig,cont, registroNuevo->sig);
}else{
return;
}
}
I expect to have the 1st list shown (which it's happening) and also the 2nd list shown with the numbers that are divisible by 3, which doesn't happen.
First of all, I admire your dedication to recursion!
The problem is that in crear2, registroNuevo->sig is uninitialized which causes a segfault. I almost always start a function that operates on a recursive linked data structure by checking if the parameter node is null. If so, I can safely continue on with the body of the function. Following this logic of protecting against nulls, we need to pass the registroNuevo node along without touching it in the case when registro->num % 3 != 0 and ensure all of its fields are initialized.
Here's the corrected function:
void crear2(nodo *registro, int cont, nodo *registroNuevo)
{
if (registro) {
if (registro->num % 3 == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = NULL;
if (registro->sig) {
registroNuevo->sig = malloc(sizeof(nodo));
}
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
crear2(registro->sig, cont, registroNuevo);
}
}
}
Having said that, this function is still a bit less than ideal for a couple reasons. First of all, the name is vague and could describe the behavior better. Also, if there are no items divisible by three, you've got a malloced node back in the calling scope that never gets initialized, so it's a bit brittle in that regard. Thirdly, even with a parameter, it feels like a highly specific function without much reusability factor that could be written iteratively inside the calling scope like:
#include <stdio.h>
#include <stdlib.h>
typedef struct nodo
{
int num;
struct nodo *sig;
} nodo;
nodo *crear(nodo *registro, int num)
{
nodo *n = malloc(sizeof(nodo));
n->num = num;
n->sig = registro;
return n;
}
void mostrar(nodo *registro)
{
if (registro)
{
printf("%d->", registro->num);
mostrar(registro->sig);
}
else puts("");
}
void free_lista(nodo *registro)
{
if (registro)
{
free_lista(registro->sig);
free(registro);
}
}
int main()
{
nodo *prin = NULL;
nodo *prin_div_3 = NULL;
for (int t; scanf("%d", &t) && t != 1000;)
{
prin = crear(prin, t);
}
nodo *tmp = prin;
while (tmp)
{
if (tmp->num % 3 == 0)
{
prin_div_3 = crear(prin_div_3, tmp->num);
}
tmp = tmp->sig;
}
mostrar(prin);
mostrar(prin_div_3);
free_lista(prin);
free_lista(prin_div_3);
return 0;
}
This isn't perfect--without tail nodes, adding to the list is a bit less than ideal, but dangling heads are eliminated, and hopefully it shows an alternate approach to organizing program logic and functions.
A few other remarks:
Always free memory that you've allocated. You can write a simple recursive routine to do so, like free_lista as shown in the above example.
Consider avoiding highly specific functions with hard-coded values like 3 and 1000. Make these parameters to maximize reusability.
crear2 never uses the cont member, and you have global constants that are unused. It's a good idea to clean these up to help clarify your debugging efforts and reduce visual clutter.
No need to cast the result of malloc.
if (registro->sig !=NULL) as the first line of a function is going to crash on a null. You don't need != NULL either. if (registro) { ... } is clearest and avoids problems with null parameters.
void crear2 (nodo *registro, int cont, nodo *registroNuevo) {
if ((registro->num % 3) == 0) {
registroNuevo->num = registro->num;
registroNuevo->sig = (nodo*)malloc(sizeof(nodo));
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo->sig);
}
else {
if (registro->sig != NULL)
crear2(registro->sig, cont, registroNuevo);
}
}
This is my approach, but you are still getting a final unexpected 0 at the last mostrar() call; and you still need to do the 'free' calls. I think you should avoid the recursive calls, there are easier ways to do it. Saludos.

How do you use a typedef struct for a FIFO?

I just started programming in C for school. I am being asked to do a program that uses a FIFO struct to resolve math problems. I got the folowing code on the internet for a FIFO, I just don't know how to use it. I tried a lot of things and I can't find anything useful on the internet or maybe that I just don't know the right thing to research but could you please help me? Thanks!
#include <stdio.h>
#include <stdlib.h>
typedef struct pile
{
int donnee;
struct pile *precedent;
} Pile;
void pile_push(Pile **p_pile, int donnee)
{
Pile *p_nouveau = malloc(sizeof *p_nouveau);
if (p_nouveau != NULL)
{
p_nouveau->donnee = donnee;
p_nouveau->precedent = *p_pile;
*p_pile = p_nouveau;
}
}
int pile_pop(Pile **p_pile)
{
int ret = -1;
if (p_pile != NULL)
{
Pile *temporaire = (*p_pile)->precedent;
ret = (*p_pile)->donnee;
free(*p_pile), *p_pile = NULL;
*p_pile = temporaire;
}
return ret;
}
void pile_clear(Pile **p_pile)
{
while (*p_pile != NULL)
{
pile_pop(p_pile);
}
}
I tried doing this:
int main()
{
int return_val;
Pile pile;
pile_push(Pile, 5);
return_val = pile_pop(Pile);
printf(return_val);
}
and got this error:
expected expression before 'Pile'
too few arguments to function 'pile_push'
You have mixed up Pile and pile which is the issue with the first warning. The functions expect a pointer to a pointer to a Pile. That is: They update the value of a pointer, so they need to be passed a reference to a pointer. Your use of printf is also wrong.
int main()
{
int return_val;
Pile *pile = NULL;
pile_push(&pile,5);
return_val = pile_pop(&pile);
printf("return_val is: %d\n",return_val);
}

Inserting at the end of queue in C

I am trying to insert node at the end of queue and facing below error . This is simple fundamental error while compiling the code but making my life hard.
#include<stdio.h>
#include<stdlib.h>
typedef struct UNIX {
char str[20];
struct UNIX *next;
}examp;
examp *head=NULL;
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
slide->next=new;
new->str=s;
new->next=NULL;
if(head==NULL)
{ head=new;
return 1;
}
return 1;
}
void display (void);
int main()
{
insert_last("hello ");
insert_last("how ");
insert_last("have ");
insert_last("you ");
insert_last("been ");
insert_last("! ");
display();
}
void display(void)
{
examp *slide;
slide=head;
while(slide->next!=NULL)
{ printf("%s ",slide->str);
slide=slide->next;
}
}
Error :stack_queue.c:27:10: error: assignment to expression with array type
new->str=s;
Update : Using strncpy reolved the error , but code is not working as expected and stopping unexpectedly.
You can't assign to a static array like that. Consider using strcpy or strncpy to copy the contents of the character string instead.
You cannot assign a string to an array! An array have its own memory, you can write or read elements in the array, but cannot assign an address.
You can eventually copy the string s contents to the array:
strncpy(new->str, s, 19);
new->str[19] = '\0'; //Close the string in case of overflow.
We used strncpy to limit the copied characters to the array size (19 chars + the ending '\0').
You can try it. Only replace in new->str=s; to strcpy(new->str, s); (ie. s will be copy in to new->str)
#include<stdio.h>
#include<stdlib.h>
typedef struct UNIX {
char str[20];
struct UNIX *next;
}examp;
examp *head=NULL;
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
slide->next=new;
strcpy(new->str, s);
new->next=NULL;
if(head==NULL)
{ head=new;
return 1;
}
return 1;
}
void display (void);
int main()
{
insert_last("hello ");
insert_last("how ");
insert_last("have ");
insert_last("you ");
insert_last("been ");
insert_last("! ");
display();
}
void display(void)
{
examp *slide;
slide=head;
while(slide->next!=NULL)
{ printf("%s ",slide->str);
slide=slide->next;
}
}
As already stated you will have to use strcpy (or strncpy) in order to assign the string.
Asides from that I wanted to mention two things:
Do not forget to free your memory allocated by malloc. Create a method to free a single node (examp) then you can also provide a method to destroy the whole list.
I would suggest to rename the variable new to avoid confusion (pure C compiler may deal with it, but C/C++ compiler will most likely get into trouble).
Considering your update:
Take a look at the following line
while(slide->next!=NULL)
At this time slide does not even exist (it is NULL), still you perform an operation on the pointer. This is the reason why the program crashes.
Your error is in the first call insert_last("hello "):
int insert_last(char *s)
{
examp *new,*slide;
slide=head;
new = (examp *)malloc(sizeof(examp));
if(!new)
return(EXIT_FAILURE);
while(slide->next!=NULL)
slide=slide->next;
when you call it first time, head is NULL, so slide becomes NULL, but you don't check it, and call it in
while(slide->next!=NULL)
Here slide is null for the frst function call

Resources