Struct with pointers changes value without reassigning - c

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;
}

Related

Getting negative numbers or zero as output of factorial in C

I've written a very simple program which calculate the factorial of a number, the problem is that from 30 to 60 approximately, it returns a negative number and from 70 it returns 0.
I don't what I've done wrong. Could this problem depend on the computing power of my computer?
Here's the code:
#include <stdio.h>
int main(){
int x, i;
long long int f = 1;
printf("Insert a number:");
scanf("%d", &x);
if (x == 0){
printf("0! = 1");
}
else {
for (i = 1; i <= x; i++){
f *= i;
}
printf("%d! รจ = %lli", x, f);
}
return 0;
}
Here is my code:
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
void Carry(int bit[],int pos)
{
int i,carray=0;
for(i=0;i<=pos;i++)
{
bit[i]+=carray;
if(bit[i]<=9)
{
carray=0;
}
else if(bit[i]>9&&i<pos)
{
carray=bit[i]/10;
bit[i]%=10;
}
else if(bit[i]>9&&i>=pos)
{
while(bit[i]>9)
{
carray=bit[i]/10;
bit[i]%=10;
i++;
bit[i]=carray;
}
}
}
}
int main()
{
int num,pos,digit,i,j,m,n;
double sum=0;
int *fact;
printf("input want to calculute factorial num:");
scanf("%d",&num);
for(i=1;i<=num;i++)
{
sum+=log10(i);
}
digit=(int)sum+1;
if(!(fact=(int *)malloc((digit+1)*sizeof(int))))
{
printf("malloc failed\n");
return 0;
}
for(i=0;i<=digit;i++)
{
fact[i]=0;
}
fact[0]=1;
for(i=2;i<=num;i++)
{
for(j=digit;j>=0;j--)
{
if(fact[j]!=0)
{
pos=j;
break;
}
}
for(j=0;j<=pos;j++)
{
fact[j]*=i;
}
Carry(fact,pos);
}
for(j=digit;j>=0;j--)
{
if(fact[j]!=0)
{
pos=j;
break;
}
}
m=0;
n=0;
for(i=pos;i>=0;i--)
{
printf("%d",fact[i]);
m++;
if(m%4==0)
{
printf(" ");
}
if(m==40)
{
printf("\n");
m=0;
n++;
if(n==10)
{
printf("\n");
n=0;
}
}
}
printf("\n\n");
return 0;
}

Why does my function go into infinite loop sometimes?

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.

Function string_to_table is breaking on 3rd if c

I am trying to create program to add two matrixes. After typing input like [12 4] program crashes when function strcat starts.
I have no idea what is wrong. func.h consists of stdio.h, _mingw.h,stdlib.h and string.h
#include"func.h"
void string_to_table(double **matrix, char inpt[])/*problematic function*/
{
printf("convertion start");
int i=strlen(inpt);
printf("%i",i);
int j=1;
int k=0,l=0;
char num[128];
double converted=0;
printf("breakpoint1");
while(j<(i-1))
{
if(inpt[j]==' ')
{
printf("first if");
converted=atof(num);
num[0]='\0';
matrix[k][l]=converted;
++l;
printf("breakpoint2");
}
else if(inpt[j]==';')
{
printf("second if");
converted=atof(num);
num[0]='\0';
matrix[k][l]=converted;
++k;
l=0;
}
else
{
printf("third if");
strcat(num,inpt[j]);/*place when everything crashes*/
}
++j;
}
printf("convert0 end");
}
void add_matrix(double **matrix1, double **matrix2,int i,int j)
{
int k=0;
int l=0;
while(k<i)
{
while(l<j)
{
matrix1[k][l]+=matrix2[k][l];
++l;
}
l=0;
++k;
}
int matrixproccesing(int *i,int *j, char m[])/*sprawdzanie poprawnosci wejscia*/
{
printf("macro start");
int columnnum=0,rownum=0,x=0,piv=0,check=0;
int textsize=strlen(m);
printf("%i",i);
printf("loop start");
printf("%i",textsize);
while(x<(textsize-1))
{
printf("%i",x);
printf("\n");
if(x==0)/*czy poczatek to [*/
{
if(m[x]!='[')
return 0;
}
else if(x==(textsize-2))/*czy koniec to]*/
{
printf("kohec");
if(m[x]==']')
break;
return 0;
}
else if((m[x]>47&&m[x]<58)||(m[x]==' ')||(m[x]=='.')||(m[x]==';')||(m[x]=='-'))/*czy liczba*/
{
if(m[x]==';')/*czy ilosc liczb w rzedzie taka sama*/
{
if(check==0)
{
check=columnnum;
}
else if(check!=columnnum)
{
return 0;
}
printf("colnum");
columnnum=0;
rownum++;
}
else if(m[x]==' ')/*czy nowa liczba/kolumna */
{
columnnum++;
}
}
++x;
}
*i=(check+1);
*j=(columnnum+1);
printf("macro end");
return 1;
}
int is_same_size(int a, int b,int c ,int d)/*test rozmiaru*/
{
if((a==c)&(b==d))
return 1;
return 0;
}
void print_da_matrix(double **matrix, int i, int j)
{
int k=0,l=0;
printf("[ ");
while(k<i)
{
while(l<j)
{
printf("%f",matrix[k][l]);
printf(" ");
}
printf(";");
l=0;
if(k<(i-1))
++k;
}
printf("]");
}
void release_the_memory(double **matrix, int i)
{
int k=0;
while(k<i)
{
free(matrix[k]);
++k;
}
free(matrix);
matrix=NULL;
}
}
int main()
{
int i=0,j=0,m1=0,m2=0,tabcr=0;
char matrix[512];
fgets(&matrix,511,stdin);
double **matrix1;
double **matrix2;
if(!matrixproccesing(&i,&j,matrix))
{
printf("zle wejscie");
return 0;
}
matrix1=(double**)malloc(i*sizeof(double *));
while(tabcr<j)
{
matrix1[tabcr]=(double*)malloc(j*sizeof(double));
++tabcr;
}
string_to_table(matrix1,matrix);
printf("\n");
printf("podaj druga macierz");
fgets(&matrix,511,stdin);
if(!matrixproccesing(&m1,&m2,matrix))
{
printf("zle wejscie");
return 0;
}
tabcr=0;
if(!is_same_size(i,j,m1,m2))
{
printf("matrixes have different size.");
return 0;
}
matrix2=(double**)malloc(i*sizeof(double *));
while(tabcr<j)
{
matrix2[tabcr]=(double*)malloc(j*sizeof(double));
++tabcr;
}
string_to_table(matrix2,matrix);
add_matrix(matrix1,matrix2,i,j);
/* print_da_matrix(matrix1,i,j);
release_the_memory(matrix1,i);
release_the_memory(matrix2,i);*/
return 0;
}

Nptel-pascal programming assignment

i am pursuing the course on programming and data structures in nptel's MOOC.
A programming assignment in the course requires us to calculate sum of selected coefficients.
Now the program i wrote calculated the answer , but i am experiencing a runtime error.
Now i had this inclination of using gets() instead of scanf() so as to speed up my input.
how do i do that?
the code is as follows:
#include<stdio.h>
int combi(int ,int);
long fact(int);
int main()
{
int r,i,v[20],p[20],t,l=1,b=0,sum=0,a=0,flag=0;
char ch='a';
scanf("%d",&r);
scanf("%d",&t);
for(i=0;i<t;i++)
{
scanf("%d",&v[0]);
if(getchar()==' ')
{
if(r<v[0])
{
while(ch!='\n')
{
scanf("%d",&v[l]);
l++;
if(getchar()=='\n')
{
p[a]=-1;
a++;
l=1;
break;
}
}
}
else
{
while(ch!='\n')
{
scanf("%d",&v[l]);
if(v[l]>v[0])
{
flag=1;
}
l++;
if(getchar()=='\n')
{
if(flag>0)
{
p[a]=-1;
a++;
l=1;
sum=0;
flag=0;
break;
}
else
{
for(b=1;b<l;b++)
{
sum=sum+combi(v[0],v[b]);
}
p[a]=sum;
a++;
sum=0;
l=1;
break;
}
}
}
}
}
}
for(i=0;i<t;i++)
{
printf("%d\t ",p[i]);
}
printf("\n");
}
int combi(int x,int y)
{
int a=fact(x)/(fact(x-y)*fact(y));
return a;
}
long fact(int z)
{
int i=1;
long f=1;
while(i<=z)
{
f=f*i;
i++;
}
return f;
}

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, ...).

Resources