Why does my function go into infinite loop sometimes? - c

I have the following code. It is running fine. But sometimes the del and ins functions are going into infinite loop but sometimes working fine. The readt function is working fine, still I have included it for your reference. What is the problem with my del and ins? Is there any memory leak?
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<math.h>
#include<unistd.h>
struct node
{ int info;
struct node *link;
};
typedef struct node m;
m *search(int,m*);
m *del(int,m*);
m *ins(int,int,m*);
int posof(int,m*);
int readt(m *t_c,char path[])
{ int t,szt=0;
FILE *tfile;
char ch;
char filename[]="/temp.txt";
strcat(path,filename);
tfile=fopen(path,"r");
if(tfile==NULL)
exit(0);
fseek(tfile, 0, SEEK_END);
szt = ftell(tfile);
fseek(tfile,0,SEEK_SET);
if(szt!=0)
{ while(1)
{ fscanf(tfile,"%d%c",&t,&ch);
t_c->info=t;
t_c->link=(m*)malloc(sizeof(m));
t_c=t_c->link;
if(ch==';')
break;
}
}
t_c->link=NULL;
//free(t_c);
fclose(tfile);
return 0;
}
m *search(int Noftarget,m *t_c)
{ int i,p1,p2;
srand(time(NULL));
for(i=0;i<100;i++)
{ p1=(1+rand()%(Noftarget));
p2=(1+rand()%(Noftarget));
t_c=del(p1,t_c);
t_c=ins(p1,p2,t_c);
break;
}
return t_c;
}
m *del(int target,m *t_h)
{ m *t_c;
int j=1,i;
t_c=t_h;
i=posof(target,t_h);
if(i==1)
{ t_c=t_c->link;
t_h=t_c;
}
else
{ while(j<i-1)
{ t_c=t_c->link;
j++;
}
t_c->link=t_c->link->link;
}
return t_h;
}
m *ins(int target,int position,m *t_h)
{ int j=0;
m *swaptarget,*t_c;
t_c=t_h;
swaptarget=(m*)malloc(sizeof(m));
swaptarget->info=target;
if(position==1)
{ swaptarget->link=t_c;
t_h=swaptarget;
}
else
{ while(j<position-2)
{ t_c=t_c->link;
j++;
}
swaptarget->link=t_c->link;
t_c->link=swaptarget;
}
free(swaptarget);
return t_h;
}
int posof(int p1,m *t_c)
{ int i=1,a=0;
while(t_c->link!=NULL)
{ if(p1==t_c->info)
{ a=i;
break;
}
t_c=t_c->link;
i++;
}
return a;
}
int main()
{ int Noftarget=8,j,r=1,count=0,noi,szd_n=0,i=0,sz;
char cwd[200];
m *t_h;
getcwd(cwd, sizeof(cwd));
t_h=(m*)malloc(sizeof(m));
readt(t_h,cwd);
t_h=search(Noftarget,t_h);
free(t_h);
return 0;
}
and the content of temp file is:
1,2,3,4,5,6,7,8;

The program contains memory leaks. Memory is allocating iteratively inside the while loop but only one pointer is removing at the end. Need to remove all allocations. And there is no need to free any pointer at the ins function rather del function needs the free operation of deleted pointer. The modified code is here:
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#include<math.h>
#include<unistd.h>
struct node
{ int info;
struct node *link;
};
typedef struct node m;
m *search(int,m*);
m *del(int,m*);
m *ins(int,int,m*);
int posof(int,m*);
int readt(m *t_c,char path[])
{ int t,szt=0;
FILE *tfile;
char ch;
char filename[]="/temp.txt";
strcat(path,filename);
tfile=fopen(path,"r");
if(tfile==NULL)
exit(0);
fseek(tfile, 0, SEEK_END);
szt = ftell(tfile);
fseek(tfile,0,SEEK_SET);
if(szt!=0)
{ while(1)
{ fscanf(tfile,"%d%c",&t,&ch);
t_c->info=t;
t_c->link=(m*)malloc(sizeof(m));
//printf("%d ",t_c->info);
t_c=t_c->link;
if(ch==';')
break;
}
}
t_c->link=NULL;
//free(t_c);
fclose(tfile);
return 0;
}
m *search(int Noftarget,m *t_c)
{ int i,p1,p2;
srand(time(NULL));
for(i=0;i<100;i++)
{ p1=(1+rand()%(Noftarget));
p2=(1+rand()%(Noftarget));
t_c=del(p1,t_c);
t_c=ins(p1,p2,t_c);
break;
}
return t_c;
}
m *del(int target,m *t_h)
{ m *t_c;
int j=1,i;
t_c=t_h;
i=posof(target,t_h);
if(i==1)
{ free(t_c);
t_c=t_c->link;
t_h=t_c;
}
else
{ while(j<i-1)
{ t_c=t_c->link;
j++;
}
free(t_c->link);
t_c->link=t_c->link->link;
}
return t_h;
}
m *ins(int target,int position,m *t_h)
{ int j=0;
m *swaptarget,*t_c;
t_c=t_h;
swaptarget=(m*)malloc(sizeof(m));
swaptarget->info=target;
if(position==1)
{ swaptarget->link=t_c;
t_h=swaptarget;
}
else
{ while(j<position-2)
{ t_c=t_c->link;
j++;
}
swaptarget->link=t_c->link;
t_c->link=swaptarget;
}
return t_h;
}
int posof(int p1,m *t_c)
{ int i=1,a=0;
while(t_c->link!=NULL)
{ if(p1==t_c->info)
{ a=i;
break;
}
t_c=t_c->link;
i++;
}
return a;
}
int main()
{ int Noftarget=7,j,r=1,count=0,noi,szd_n=0,i=0,sz;
char cwd[200];
m *t_h;
getcwd(cwd, sizeof(cwd));
t_h=(m*)malloc(sizeof(m));
readt(t_h,cwd);
print_tsp(t_h);
t_h=search(Noftarget,t_h);
print_tsp(t_h);
while(t_h!=NULL)
{ free(t_h);
t_h=t_h->link;
}
return 0;
}
It is checked by valgrind and does not have any memory leak.

Related

why this show() function produce two * and the element will stop sometimes .There is no error in the code

This is a plane game function I wrote. I use a two-dimensional array to represent the game variables but The running result is abnormal, and * will jump suddenly.
And there will be two * , at the same time, and the plane also will stop
There should be no two * in the process of traversing the two-dimensional array. I tried to modify the position of * but I still couldn't.It's OK to run part of the code alone, but when you use the key operation, the program makes an error, but I don't know what's wrong
#include<stdio.h>
#include <windows.h>
#include<stdlib.h>
#include<conio.h>
#define enemynum 3
int element [20][30];
int position_x,position_y;
int enemy_x[enemynum],enemy_y[enemynum];
int score;
void gotoxy(int x, int y)
{
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
COORD pos;
pos.X = x;
pos.Y = y;
SetConsoleCursorPosition(handle, pos);
}
void HideCursor()
{
CONSOLE_CURSOR_INFO cursor_info = {1,0};
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void startup()
{ element[20][30]={0};
position_x=10;position_y=15;
element[position_x][position_y]=1;
for(int k=0;k<enemynum;k++)
{
enemy_x[k]=rand()%3;enemy_y[k]=rand()%20;
element[enemy_x[k]][enemy_y[k]]=3;
}
HideCursor();
}
This is an encapsulated pointer callback function. I don't think we need to consider the above functions
void show()
{ int i,j;
gotoxy(0,0);
for(i=0;i<20;i++)
{
for(j=0;j<30;j++)
{ if(element[i][j]==1)
{
printf("*");
}else if(element[i][j]==3)
{
printf("#");
}
else
printf(" ");
}
printf("\n");
}
}
void updatewhithout()
{
int i,j;
for(i=0;i<20;i++)
{
for(j=0;j<30;j++)
{
if(element[i][j]==2)
{
element[i][j]=0;
if(i>0)
element[i-1][j]=2;
}
}
} static int flag;
if(flag<20)
flag++;
if(flag==20)
{ for(int k=0;k<enemynum;k++)
{
if(enemy_x[k]==20)
{
enemy_x[k]=rand()%3;
enemy_y[k]=rand()%20;
}
element[enemy_x[k]][enemy_y[k]]=0;
enemy_x[k]++;
element[enemy_x[k]][enemy_y[k]]=3;
flag=0;
}
}
}
void updatewhith()
{ char ch;
if( kbhit())
ch=getch();
if(ch=='a')
{ element[position_x][position_y]=0;
position_y--;
element[position_x][position_y]=1;
}
if(ch=='d')
{ element[position_x][position_y]=0;
position_y++;
element[position_x][position_y]=1;
}
}
int main()
{startup();
while(1)
{show();
updatewhithout();
updatewhith();
}
}

I need help to convert from infix to postfix in C

I was practising some data structures problems that I did previously but this time I don't know what is going wrong in my code. I looked over a long time but I did not found the mistake. When I'm printing I'm just getting the first character and it looks like e is not being updated. But I've written e++.
#include<stdio.h>
#include "ctype.h"
int stack[20];
int top = -1;
void push(int x)
{
stack[++top] = x;
}
int pop()
{
return stack[top--];
}
int priorityof(char x)
{
if(x=='(')
return 3;
else if(x=='+'|| x=='-')
return 1;
else if(x=='*'|| x=='/')
return 2;
}
int main()
{
char exp[20];
char *e;
e=exp;char x;
scanf("%c",exp);
while(*e!='\0')
{
if(isalnum(*e))
{
printf("%c", *e);
}
else if(*e=='(')
{
push(*e);
}
else if(*e==')')
{
while((x=pop())!='(')
printf("%c",x);
}
else {
while (priorityof(stack[top]) >= priorityof(*e)) {
printf("%c", pop());
push(*e);
}
}
e++;
}
while(top!=-1)
{
printf("%c",pop());
}
}
%c is for single character and reading your question it seems like you are giving more than one character so its a string, use %s.
#include<stdio.h>
#include "ctype.h"
int stack[20]; int top = -1;
void push(int x) {
stack[++top] = x;
}
int pop() { return stack[top--]; }
int priorityof(char x) {
if(x=='(') return 3;
else if(x=='+'|| x=='-') return 1;
else if(x=='*'|| x=='/') return 2;
}
int main() {
char exp[20];
char *e;
e=exp;char x;
scanf("%s",exp);
while(*e!='\0') { if(isalnum(*e)) { printf("%c", *e); } else if(*e=='(') { push(*e); } else if(*e==')') { while((x=pop())!='(') printf("%c",x); } else { while (priorityof(stack[top]) >= priorityof(*e)) { printf("%c", pop()); push(*e); } } e++; } while(top!=-1) { printf("%c",pop()); } }

Struct with pointers changes value without reassigning

I debugged the program below. It finds the correct result but then mmat in the recursive function ri gets changed without reassigning it by this part of the code pmat[q][h].ptes=NULL; and i get as final result that all the non pre-assigned pointers are null. I got the same problem with a global variable mat **mmat instead of passing it by reference in ri. Does anybody know the reason?
typedef struct tes_{
struct seg_{
char c;
int v;
}seg[2];
}tes;
typedef struct mat_{
tes *ptes;
int rot;
} mat;
int max=0;
int main()
{
FILE *f; char frase[M], buff[M]; int n,i,j,r,c,q=0,z=0,e=0,*pos,*esc; tes *vtes; mat **pmat, **mmat;
printf("Inserire nome file input tessere: "); scanf("%s",frase);
f=fopen(frase,"r");
if (f==NULL) exit(1);
fgets(frase,50,f); sscanf(frase,"%d",&n);
vtes=malloc(n*sizeof(tes));
for (i=0;i<n;i++) {fgets(frase,M,f); sscanf(frase,"%c %d %c %d",&(vtes[i].seg[0].c),&(vtes[i].seg[0].v),&(vtes[i].seg[1].c),&(vtes[i].seg[1].v));}
fclose(f);
printf("Inserire nome file input scacchiera: "); scanf("%s",frase);
f=fopen(frase,"r");
if (f==NULL) exit(1);
fgets(frase,M,f); sscanf(frase,"%d %d",&r,&c);
esc=(int*)malloc(r*c*sizeof(int));
pmat=(mat **)malloc(r*sizeof(mat *));
mmat=(mat **)malloc(r*sizeof(mat *));
for (i=0;i<r;i++) {pmat[i]=(mat *)malloc(c*sizeof(mat)); mmat[i]=(mat *)malloc(c*sizeof(mat));}
for (i=0;i<r;i++) {
fgets(frase,M,f); q=0;
for (j=0;j<c;j++) {
z=0;
while (frase[q]!='/') {
buff[z]=frase[q]; q++; z++;
}
q++; buff[z]='\0'; z=0;
if (atoi(buff)==-1) pmat[i][j].ptes=NULL;
else {pmat[i][j].ptes=&(vtes[atoi(buff)]); esc[e]=atoi(buff); e++;}
while (frase[q]!=' ' || frase[q]=='\n' || frase[q]=='\0') {
buff[z]=frase[q]; q++; z++;
}
q++; buff[z]='\0'; pmat[i][j].rot=atoi(buff);
}
}
pos=(int *)malloc((n-e)*sizeof(int)); q=0;
for(i=0;i<n;i++) { // pos contiene tutte le tessere inseribili
for (j=0;j<e;j++) if(esc[j]==i) break;
if (j>=e) {pos[q]=i; q++;}
}
ri(pmat,&mmat,vtes,pos,n-e,r,c);
printf("Max valore %d\n",max);
for (i=0;i<r;i++) {
for (j=0;j<c;j++) {
printf("%c %d // %c %d\t",mmat[i][j].ptes->seg[(0+mmat[i][j].rot)%2].c,mmat[i][j].ptes->seg[(0+mmat[i][j].rot)%2].v,mmat[i][j].ptes->seg[(1+mmat[i][j].rot)%2].c,mmat[i][j].ptes->seg[(1+mmat[i][j].rot)%2].v);
}
printf("\n");
}
return 0;
}
void ri(mat **pmat, mat ***mmat, tes *vtes, int *pos, int i, int r, int c){
int j,q,h,z,*pos2;
if (i==0) {
if(check(pmat,vtes,r,c)) {
*mmat=pmat;
}
return;
}
for (j=0;j<i;j++) {
for (q=0;q<r;q++) {
for (h=0;h<c;h++) {
if (pmat[q][h].ptes==NULL) break;
}
if (h<c) break;
}
if (q==r && h==c) return;
pos2=malloc((i-1)*sizeof(int));
for (z=0;z<i;z++){
if (z<j) pos2[z]=pos[z];
else if (z>j) pos2[z-1]=pos[z];
}
pmat[q][h].ptes=&(vtes[pos[j]]);
pmat[q][h].rot=0;
ri(pmat,mmat,vtes,pos2,i-1,r,c);
pmat[q][h].rot=1;
ri(pmat,mmat,vtes,pos2,i-1,r,c);
free(pos2);
if ((*mmat)[0][1].ptes==NULL) {
printf("prob");
}
pmat[q][h].ptes=NULL;
if ((*mmat)[0][1].ptes==NULL) {
printf("prob");
}
}
}
int check(mat **pmat,tes *vtes, int r, int c){
int i,j, cont=0;
for (i=0;i<r;i++) {
for (j=0;j<c-1;j++) {
if (pmat[i][j].ptes->seg[(0+pmat[i][j].rot)%2].c!=pmat[i][j+1].ptes->seg[(0+pmat[i][j+1].rot)%2].c) break;
}
if (j==c-1) {for (j=0;j<c;j++) cont+=pmat[i][j].ptes->seg[(0+pmat[i][j].rot)%2].v;}
}
for (i=0;i<c;i++) {
for (j=0;j<r-1;j++) {
if (pmat[j][i].ptes->seg[(1+pmat[j][i].rot)%2].c!=pmat[j+1][i].ptes->seg[(1+pmat[j+1][i].rot)%2].c) break;
}
if (j==r-1) {for (j=0;j<r;j++) cont+=pmat[j][i].ptes->seg[(1+pmat[j][i].rot)%2].v;}
}
if (cont>max) {
max=cont;
return 1;
}
return 0;
}

What is causing my blackjack program to crash before doing anything?

When I run my program, it will print "Welcome to Blackjack! Rules: " and then an error window will come up saying "Blackjack.exe has stopped working and I have to close the program. In the compiler window it says "Process terminated". How do I stop this from happening?
Is one of the loops not working correctly?
My code:
#include <stdio.h>
#include <stdlib.h>
void Initializedeck(int[]);
void Shuffledeck(int[]);
void displayscore(int, int);
int hdrawcards(int[], int[]);
char getsuit(int);
int cdrawcards(int[], int[]);
int main()
{
int deck[52];
char cont;
int hcherries=10;
int ccherries=10;
int hcards[10];
int ccards[10];
int htotal;
int ctotal;
printf("Welcome to Blackjack!\n");
printf("Rules: \n ");
Initializedeck(deck);
cont='y';
while(cont=='y')
{
Shuffledeck(deck);
system("cls");
displayscore(hcherries, ccherries);
htotal=hdrawcards(hcards, deck);
ctotal=cdrawcards(ccards, deck);
if(htotal>ctotal)
{
printf("You Win!");
}
else
{
printf("Computer Wins. :( ");
}
printf("Do you want to continue?(y/n)");
scanf("%c", &cont);
}
return 0;
}
void Initializedeck(int deck[])
{
int i=0;
while(i<52)
{
deck[i]=i;
i++;
}
}
void Shuffledeck(int deck[])
{
int hold;
int max=51;
int random;
while(max>=0)
{
random=rand()%(max)+1;
hold=deck[max];
deck[max]=random;
random=hold;
max--;
}
}
void displayscore(int hcherries, int ccherries)
{
printf("Human: %i(cherries) Computer: %i(cherries)", hcherries, ccherries);
}
int hdrawcards(int hcards[], int deck[])
{
char answer;
int i=0;
int score=0;
int total=0;
char rank;
int worth;
char suit;
int card;
printf("Do you want to draw a card? (y/n)");
scanf("%c", &answer);
while(answer=='y' && total<21)
{
score=score+deck[i];
hcards[i]=deck[i];
card=hcards[i];
worth=hcards[i]%13;
if(worth==10)
{
rank='T';
}
else if (worth==11)
{
rank='J';
}
else if (worth==12)
{
rank='Q';
}
else if (worth==13)
{
rank='K';
}
else if(worth==1)
{
rank='A';
}
else
{
rank=worth;
}
if(worth>10)
{
worth=10;
}
total=total+worth;
suit=getsuit(card);
printf("%c%c\n", rank, suit);
printf("Total: %i", total);
i++;
scanf("%c", &answer);
}
return total;
}
int cdrawcards(int ccards[], int deck[])
{
int i=26;
int total;
int score;
int worth;
char rank;
char suit;
int card;
while(total<18)
{
score=score+deck[i];
ccards[i]=deck[i];
card=ccards[i];
worth=ccards[i]%13;
if(worth==10)
{
rank='T';
}
else if (worth==11)
{
rank='J';
}
else if (worth==12)
{
rank='Q';
}
else if (worth==13)
{
rank='K';
}
else if(worth==1)
{
rank='A';
}
else
{
rank=worth;
}
if(worth>10)
{
worth=10;
}
total=total+worth;
suit=getsuit(card);
printf(" %c%c\n", rank, suit);
printf(" Total: %i", total);
i++;
}
return total;
}
char getsuit(int card)
{
char suit;
if(card<13)
{
suit='S';
}
else if(card>=13 && card<26)
{
suit='H';
}
else if(card>=26 && card<39)
{
suit='D';
}
else if(card>=39 && card<52)
{
suit='C';
}
return suit;
}
You have an array overflow in cdrawcards():
int ccards[10];
...
ctotal = cdrawcards(ccards, deck);
...
int cdrawcards(int ccards[], int deck[])
{
int i = 26;
...
ccards[i] = deck[i]; //Overflow, ccards[] only has 10 elements
Either change the initial value of i or make the array larger int ccards[52]. I would also add an explicit check in cdrawcards() and hdrawcards() to ensure you don't overflow the arrays, like:
while (total < 18 && i < 10)
For example, in hdrawcards() you can overflow the array if you get a bunch of low value cards in a row (ex: 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3(overflow), 3, ...).

Is this program to get the mininmum value in a stack of O(1) complexity?

I have implemented push pop and get minimum in O(1) complexity. I have seen many solutions in C++. This is an implementation in C itself. Is the following program correct?
#include <stdio.h>
#include <stdlib.h>
int stack[15],aux[15];
int top=-1,count=-1,aux_count=-1,temp_aux=-1;
void push_auxilary(int ele)
{
aux[++aux_count] = ele;
}
void push_stack(int ele)
{
stack[++top]=ele;
}
void push(int ele)
{
if(top < 0 && aux_count < 0)
{
push_auxilary(ele);
push_stack(ele);
}
else
{
if(ele > aux[aux_count])
{
push_auxilary(aux[aux_count]);
push_stack(ele);
}
else
{
push_stack(ele);
push_auxilary(ele);
}
}
}
int pop_stack()
{
return stack[top--];
}
int pop_auxilary()
{
return aux[aux_count--];
}
int pop()
{
int a = pop_stack();
pop_auxilary();
return a;
}
void display()
{
for (int i = top; i >= 0; i--)
{
printf("%d\n",stack[i]);
/* code */
}
}
int get_min()
{
return aux[aux_count];
}
int main(int argc, char const *argv[])
{
int i=0;
push(5);
push(9);
push(1);
push(6);
push(1);
push(54);
push(34);
push(9);
push(3);
push(4);
push(7);
push(12);
push(02);
printf("the %d\n",get_min() );
for (i = aux_count; i >= 0; i--)
{
printf("%d\n",aux[i]);
}
return 0;
}
Looks like it gets the job done in O(1) indeed. Algorithmic-ally correct, but terrible from code reusage point of view.

Resources