please help me to find Bug in my Code (segmentation fault) - c

i am tring to solve this http://www.spoj.com/problems/LEXISORT/ question
it working fine in visual studio compiler and IDEone also but when i running in SPOJ compiler it is getting SEGSIGV error
Here my code goes
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char *getString();
void lexisort(char **str,int num);
void countsort(char **str,int i,int num);
int main()
{
int num_test;
int num_strings;
char **str;
int i,j;
scanf("%d",&num_test);
for(i=0;i<num_test;i++)
{
scanf("%d",&num_strings);
str=(char **)malloc(sizeof(char *)*num_strings);
for(j=0;j<num_strings;j++)
{
str[j]=(char *)malloc(sizeof(char)*11);
scanf("%s",str[j]);
}
lexisort(str,num_strings);
for(j=0;j<num_strings;j++)
{
printf("%s\n",str[j]);
free(str[j]);
}
free(str);
}
return 0;
}
void lexisort(char **str,int num)
{
int i;
for(i=9;i>=0;i--)
{
countsort(str,i,num);
}
}
void countsort(char **str,int i,int num)
{
int buff[52]={0,0},k,x;
char **temp=(char **)malloc(sizeof(char *)*num);
for(k=0;k<52;k++)
{
buff[k]=0;
}
for(k=0;k<num;k++)
{
if(str[k][i]>='A' && str[k][i]<='Z')
{
buff[(str[k][i]-'A')]++;
}
else
{
buff[26+(str[k][i]-'a')]++;
}
}
for(k=1;k<52;k++)
{
buff[k]=buff[k]+buff[k-1];
}
for(k=num-1;k>=0;k--)
{
if(str[k][i]>='A' && str[k][i]<='Z')
{
x=buff[(str[k][i]-'A')];
temp[x-1]=str[k];
buff[(str[k][i]-'A')]--;
}
else
{
x=buff[26+(str[k][i]-'a')];
temp[x-1]=str[k];
buff[26+(str[k][i]-'a')]--;
}
}
for(k=0;k<num;k++)
{
str[k]=temp[k];
}
free(temp);
}

Generally speaking, these online judge programs give an example input (in this case, that input appears to work perfectly), but also use a set of harder hidden inputs.
In this case, what happens if the input string has a space in it? For example, an input of:
1
2
hello orld
whateverss
In this case, your scanf("%s",str[j]); will not properly read that input line. I'd suggest switching over to a getline style interface, rather than a scanf style interface.

Related

Very Basic Encryption

#include <stdio.h>
int limit;
char alp[26]={'a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','w','x','y','z'};
void encode(char message[21],char enc_message[21],int key);
void decode(char enc_message[21],char dec_message[21],int key);
main()
{
int key,i=0,j=0;
char message[21];
char enc_message[21];
char dec_message[21];
char encrypted[21];
char a='\0';
printf("Input the characters to encrypt\n");
while(i<21 && a!='\n')
{
scanf("%c",&a);
message[i]=a;
i=i+1;
}
for(i=0;;i++) /*custom strlen*/
{
if( message[i]= '\0')
{
limit=i;
break;
}
}
printf("Input the key");
scanf("%d",key);
for(i=0;i<21;i++)
{
enc_message[i]=message[i];
}
encode(message[21],enc_message[21],key);
for(i=0;i<21;i++)
{
dec_message[i]=enc_message[i];
}
for(i=0;i<limit;i++)
{
printf("%c",enc_message[i]);
}
printf("\n\n");
decode(enc_message[21],dec_message[21],key);
for(i=0;i<limit;i++)
{
printf("%c",dec_message[i]);
}
}
void encode(char message[21],char enc_message[21],int key)
{
/*char temp[21];*/
int x,y;
for(x=0;x<limit;x++) /* message check */
{
for(y=0;y<26;y++) /* <----- alphabet check */
{
if (enc_message[x]==alp[y]) enc_message[x]=alp[y+key];
}
}
}
/*------------------------------------------------------------------------*/
void decode(char enc_message[21],char dec_message[21],int key)
{
int x,y;
for (x=0;x<limit;x++)
{
for(y=0;y<26;y++)
{
if (dec_message[x]==alp[y+key]) dec_message[x]=alp[y];
}
}
}
The compiler says,the mistake has to do with the way I call functions(and write them)and says: passing argument1 of 'encode' makes pointer from integer without a cast ,and that is for argument 2 of 'encode' and the exact same for 'decode'
Thanks in advance!
You are passing a single element and it's not even a valid element, try
decode(enc_message, dec_message, key);
Also, format your code so it's readable that is really important, and looping to compute the length of the string to use it in another loop is not a very smart thing, print it in a loop like
for (int i = 0 ; enc_message[i] != '\0' ; ++i) ...
also, don't over use break, just think about the logical condition for the loop, it's the same one where you break. Code is much more readable if the condition appears in the right place.

Swap using only two variables not working

I was writing a C code for quick sort but something went wrong. After some debugging i finally found where my code was going wrong.
When i replaced
{
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
}
with
{
tmp=a[lp];
a[lp]=a[ub];
a[ub]=tmp;
}
my code started working.
I am Curious to know why my initial implementation of swapping didn't work?
Can anyone help me?
#include<stdio.h>
#define swap(a,b) (a)=(a)+(b);b=(a)-(b);(a)=(a)-(b);
int a[]={7,1,5,2,3};
int partition(int lb,int ub)
{
int k,hp,lp;
k=a[ub];
lp=lb-1;
for(hp=lb;hp<ub;hp++)
{
if(a[hp]<k)
{
lp++;
int tmp=a[lp];
a[lp]=a[hp];
a[hp]=tmp;
}
}
lp++;
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
return lp;
}
void quicksort(int lb,int ub)
{
if(lb<ub)
{
int pos=partition(lb,ub);
quicksort(lb,pos-1);
quicksort(pos+1,ub);
}
}
int main()
{
quicksort(0,4);
int i;
for(i=0;i<5;i++)printf("%d ",a[i]);
printf("\n");
return 0;
}
You need to consider what happens when lp == ub (ie. you are being asked to swap an element with itself).
Change it to this:
if (lp != ub) {
a[lp]+=a[ub];
a[ub]=a[lp]-a[ub];
a[lp]=a[lp]-a[ub];
}
Example: http://ideone.com/AS1Dgf

Why do i get this runtime error in this C programme? Please show me what's wrong

The task can be found here: http://www.talentbuddy.co/challenge/51846c184af0110af3822c32
And my programme regarding this task is the following:
#include <stdio.h>
#include<string.h>
void tokenize_query(char *query, char *punctuation) {
int i,j,ok=1,k,t;
char x[1000];
for(i=0;i<strlen(query);i++)
{
ok=1;
for(j=0;j<strlen(punctuation);j++)
{
if(query[i]==punctuation[j] || query[i]==' ')
ok=0;
}
if(ok!=0)
{
x[k]=query[i];
k++;
}
else {
for(t=0;t<k;t++)
{
printf("%c",x[t]);
}
k=0;
printf("\n");
}
}
}
k is uninitialised in the line
x[k]=query[i];
so you'll probably try to write beyond the end of the memory allocated for x.
The easiest fix is to initialise k when you declare it
int i,j,ok=1,k=0,t;
// ^^

Spoj - Mixtures

Ok this has been driving me crazy. I solved a problem on spoj called MIXTURES (http://www.spoj.com/problems/MIXTURES/). I don't know why i keep getting segmentation fault. There is also one catch in the problem that there is no explicit indicator for end of input. I think I have handled it correctly but correct me if I am wrong. Here is my code
#include<stdio.h>
#include<stdlib.h>
typedef struct temp
{
int modSum; //the modular sum of the cluster
int smoke; //the minimum smoke that a cluster can give.
}clusterInfo;
int fxDP(int *A,int len)
{
int i,j,k,smoke1,smoke2;
clusterInfo **dpArr=(clusterInfo **)malloc(sizeof(clusterInfo *)*(len-1));
for(i=0;i<len-1;i++)
dpArr[i]=(clusterInfo *)malloc(sizeof(clusterInfo)*(len-i-1)); //len- ( (i+2) -1)= len-i-1
//dpArr[i] gives info of all clusters of length i+2
//base case for clusterLength=2
for(i=0;i<len-1;i++)
{
dpArr[0][i].modSum=(A[i]+A[i+1])%100;
dpArr[0][i].smoke=A[i]*A[i+1];
}
//endBase Case
//induction
for(i=1;i<len-1;i++) //lengthOfCluster=i+2
{
for(j=0;j<len-i-1;j++) //len-i-1+i+2-1=len
{
smoke1=(dpArr[i-1][j].modSum*A[j+(i+2)-1]) + dpArr[i-1][j].smoke;
smoke2=(A[j]*dpArr[i-1][j+1].modSum) + dpArr[i-1][j+1].smoke;
dpArr[i][j].smoke=smoke1<smoke2 ? smoke1:smoke2 ;
dpArr[i][j].modSum=(dpArr[i-1][j].modSum+A[j+(i+2)-1])%100;
}
}
int result=dpArr[len-2][0].smoke;
free(dpArr);
return result;
}
int main()
{
int *A; int len,i;
while(1)
{
scanf("%d",&len);
if(feof(stdin)) break;
A=(int *)malloc(sizeof(int)*len);
for(i=0;i<len;i++)
scanf("%d",&A[i]);
printf("%d\n",fxDP(A,len));
}
return 0;
}
int result=dpArr[len-2][0].smoke;
What happens if len=1 ??

Longest Common Subsequence-Segmentation fault

I have to write a program to determine the longest common sub sequence.
Input:
The first argument will be a file that contains two strings per line, semicolon delimited. You can assume that there is only one unique subsequence per test case. e.g.
XMJYAUZ;MZJAWXU
Output:
The longest common subsequence. Ensure that there are no trailing empty spaces on each line you print. e.g.
MJAU
I am using Dev C++ .. And it is compiling Fine!...But this question is a programming challenge and when i submit my answer it's showing me a segmentation fault!
I have written the following code and i am getting a Segmentation Fault where am i wrong?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char str1[100],str2[100];
int len1;
int len2;
void printLCS(char b[len1][len2],char str1[],int i,int j)
{
if(i==0 || j==0)
return;
if(b[i][j]=='c')
{
printLCS(b,str1,i-1,j-1);
printf("%c",str1[i-1]);
}
else if(b[i][j]=='l')
printLCS(b,str1,i,j-1);
else
printLCS(b,str1,i-1,j);
}
void Seq(char str1[],char str2[])
{
int i,j;
len1=strlen(str1);
len2=strlen(str2);
int LCS[len1+1][len2+1];
char b[len1][len2];
for(i=0;i<=len1;i++)
{
LCS[i][0]=0;
}
for(j=0;j<=len2;j++)
{
LCS[0][j]=0;
}
for(i=1;i<=len1;i++)
{
for(j=1;j<=len2;j++)
{
if(str1[i-1]==str2[j-1])
{
LCS[i][j]=1+LCS[i-1][j-1];
b[i][j]='c';
}
else if(LCS[i-1][j]>=LCS[i][j-1])
{
LCS[i][j]=LCS[i-1][j];
b[i][j]='u';
}
else
{
LCS[i][j]=LCS[i][j-1];
b[i][j]='l';
}
}
}
printLCS(b,str1,len1,len2);
}
int main(int argc,char *argv[])
{
if(argc!=2)
{
printf("Invalid Number of Arguments:\n");
exit(0);
}
FILE *fp;
fp=fopen(argv[1],"r");
if(fp==NULL)
{
printf("File can't be opened:\n");
exit(0);
}
char c;
c=fgetc(fp);
while(c!=EOF)
{
int k=0;
if(c=='\n')
c=fgetc(fp);
while(c!=';')
{
str1[k]=c;
k++;
c=fgetc(fp);
}
str1[k]='\0';
c=fgetc(fp);
k=0;
while(c!=EOF && c!='\n')
{
str2[k]=c;
k++;
c=fgetc(fp);
}
str2[k]='\0';
Seq(str1,str2);
printf("\n");
if(c==EOF)
{
break;
}
else
c=fgetc(fp);
}
return 0;
}
I dont know system of this site but;
i compiled with no error,
and result was true.
You didnt close file. Maybe memory leak etc. didnt allowed by site.
And, dont use global variables, unless you dont know another solution
this usage is very very bad! ISO C90 forbids this, anyway
int len1;
int len2;
void printLCS(char b[len1][len2]...
good luck.
If you've got access to a Mac or Linux system, there's a fantastic tool called valgrind which can help you track down these kinds of errors: basically it runs your program in a virtual machine and monitors what it reads and writes to memory.
Whilst I can't compile your code, I'm pretty suspicious about this for loop:
for(i=1;i<=len1;i++)
{
for(j=1;j<=len2;j++)
{
if(str1[i-1]==str2[j-1])
{
LCS[i][j]=1+LCS[i-1][j-1];
b[i][j]='c';
}
else if(LCS[i-1][j]>=LCS[i][j-1])
{
LCS[i][j]=LCS[i-1][j];
b[i][j]='u';
}
else
{
LCS[i][j]=LCS[i][j-1];
b[i][j]='l';
}
}
}
Arrays in C and C++ start at 0, so the maximum offset you're interested in is probably strlen - 1. Try changing your for loops to
for(i=1;i<len1;i++)
{
for(j=1;j<len2;j++)
{
...
}
}

Resources