Can I use macro instead of recursion to avoid segmantion fault? - c

This is an extended question from
How can i remove this Segmentation fault in C Program
here segmentation fault occur because of stack overflow due to recursion so manny times
so i have changed his code like this..
make a MACRO insted of that function so function call is removed
#include <stdio.h>
static inline void p(char *a, int b);
#define MAGIC(a,b) p(a,b)
void p(char *a, int b)
{
static long int i = 0;
if (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
return MAGIC(a, b);
} else
{
return;
}
}
int main()
{
char *a = "HI";
int b = 10;
MAGIC(a, b);
printf("\nComplete");
return 0;
}
still i am getting segmentation fault ...still stack overflow.... why?

Change return MAGIC(a, b); to
goto START; and add a START label in the beginning of the function.
Edit:
Example using a while loop:
void p(char *a, int b)
{
static long int i = 0;
while (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
}
}
Example using a for loop:
void p(char *a, int b)
{
long int i = 0; // static seems wrong here
for (;i != 350000; i++)
{
printf("\n%ld \t at Hi hello", i);
}
}

No, it will not work. A macro is just a text copy-paste, so the result is still the same.
So your code will be expanded as:
void p(char *a, int b)
{
static long int i = 0;
if (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
return p(a, b);
} else
{
return;
}
}
int main()
{
char *a = "HI";
int b = 10;
p(a, b);
printf("\nComplete");
return 0;
}
which still has the recursion and will likely stackoverflow.
EDIT : One way to redesign the algorithm is as follows:
void p(char *a, int b)
{
long int i = 0;
while (i != 350000)
{
printf("\n%ld \t at Hi hello", i);
i++;
}
}

Related

I got a strange error when printing a matrix and passing it to various functions

I got this error
*** stack smashing detected ***: terminated
Abortado (núcleo despejado)
*** stack smashing detected ***: terminated
Abortado (núcleo despejado)
when i choose a value from line 8 example like 8A or 8C.
but the function play still makes what need but when the board is printed it doesn't print line 8 like it should.
#include <stdio.h>
#include <string.h>
//void init_board(char board[8][8]){
// for(int i=0;i<8;i++){
// board[i][j]='.';
// }
// }
// board[3][3]='o';
// board[4][4]='o';
// board[3][4]='x';
// board[4][3]='x';
//}
void init_board(char board[8][8]){
for(int i=0;i<8;i++){
for(int j=0;j<8;j++){
board[i][j]='.';
}
}
board[3][3]='o';
board[4][4]='o';
board[3][4]='x';
board[4][3]='x';
board[5][2]='x';
board[5][3]='o';
board[6][1]='x';
board[3][0]='o';
board[3][1]='o';
board[4][1]='x';
board[2][5]='o';
board[2][4]='x';
}
void print_board(char board[8][8]){
printf(" A B C D E F G H");
for(int i=0;i<8;i++){
printf("\n");
printf("%d ",i+1);
for(int j=0;j<8;j++){
printf("%c ",board[i][j]);
}
}
}
int count_flips_dir(char board[8][8],int line, char col,int delta_line,int delta_col,char color){
int i;
if(board[line+delta_line][col+delta_col]=='.'){
return 0;
}
for(i=0;board[line+delta_line][col+delta_col]!=color;i++){
line=line+delta_line;
col=col+delta_col;
if(board[line+delta_line][col+delta_col]=='.'){
return 0;
}
}
return i;
}
int flanked(char board[8][8],int line,char col,char color ){
int NN = count_flips_dir(board,line,col,-1,0,color);
int ND = count_flips_dir(board,line,col,-1,1,color);
int NE = count_flips_dir(board,line,col,-1,-1,color);
int SS = count_flips_dir(board,line,col,1,0,color);
int SD = count_flips_dir(board,line,col,1,1,color);
int SE = count_flips_dir(board,line,col,1,-1,color);
int D = count_flips_dir(board,line,col,0,1,color);
int E = count_flips_dir(board,line,col,0,-1,color);
return NN+NE+ND+SD+SE+SS+E+D;
}
void changeboard(char board[8][8],int line, char col,int delta_line,int delta_col,char color){
int i;
for(i=0;board[line+delta_line][col+delta_col]!=color;i++){
board[delta_line+line][delta_col+col]=color;
line=line+delta_line;
col=col+delta_col;
}
}
void change(char board[8][8],int line,char col,char color){
if (count_flips_dir(board,line,col,-1,0,color)>0){
changeboard(board,line,col,-1,0,color);
}
if (count_flips_dir(board,line,col,-1,1,color)>0){
changeboard(board,line,col,-1,1,color);
}
if (count_flips_dir(board,line,col,-1,-1,color)>0){
changeboard(board,line,col,-1,-1,color);
}
if (count_flips_dir(board,line,col,1,0,color)>0){
changeboard(board,line,col,1,0,color);
}
if (count_flips_dir(board,line,col,1,-1,color)>0){
changeboard(board,line,col,1,-1,color);
}
if (count_flips_dir(board,line,col,1,1,color)>0){
changeboard(board,line,col,1,1,color);
}
if (count_flips_dir(board,line,col,0,1,color)>0){
changeboard(board,line,col,0,1,color);
}
if (count_flips_dir(board,line,col,0,-1,color)>0){
changeboard(board,line,col,0,-1,color);
}
}
void play(char board[8][8],int line,char col,char color){
board[line][col]=color;
change(board,line,col,color);
print_board(board);
}
int main(){
int l;
char c;
char board[8][8];
init_board(board);
print_board(board);
printf("\nEscolha a sua Jogada: ");
scanf("%d %c", &l, &c);
c=c-'A';
l=l-1;
//teste função count_flips_dir
//printf("%d",count_flips_dir(board,l,c,1,1,'o'));
//teste funçao flanked
//printf("\n%d",flanked(board,l,c,'o'));
if (board[l][c]=='.'){
if(flanked(board,l,c,'o')>0){
play(board,l,c,'o');
}
}
return 0;
}
The function change_board has an infinite loop and overwrites board cells beyond the board boundaries, causing undefined behavior, in your case corrupting stack memory.
The logic is incorrect. You should test boundary cases so delta_line+line and delta_col+col stay in the proper range [0..7] in count_flips_dir too.

Printing all ASCII characters between two given characters in C

I have made a program to print out all ASCII character between two given character but then I write it in functions. The output of two these programs are different. I tried using pointer to pass variables by reference but the output is unlikely to be like the first program. What should I do for making it correctly ?
Here is the first program in C by using linear programming.
#include <stdio.h>>
int main()
{
char a,b,tmp;
int d;
scanf("%c%c",&a,&b);
if(a>b)
{
tmp=a;
a=b;
b=tmp;
}
d = b - a;
for (char c = a+1;c<b;c++)
{
printf("%c : %d, %o, %X\n",c,c,c,c);
}
}
Here is the other program in functions.
#include <stdio.h>>
void ascii(char a,char b);
int main()
{
char a,b,tmp;
int d;
printf("Enter 2 character => ");
scanf("%c%c",&a,&b);
ascii(&a,&b);
}
void ascii(char a,char b)
{
int d;
if (a>b)
{
char tmp= a;
a=b;
b=tmp;
}
d=b-a;
for (char c=a+1;c<b;c++)
{
printf("%c : %d, %o, %X\n",c,c,c,c);
}
}
you should not pass the addresses of your variables to your function the correct one is
#include <stdio.h>>
void ascii(char a,char b);
int main()
{
char a,b,tmp;
int d;
printf("Enter 2 character => ");
scanf("%c%c",&a,&b);
ascii(a,b);
}
void ascii(char a,char b)
{
int d;
if (a>b)
{
char tmp= a;
a=b;
b=tmp;
}
d=b-a;
for (char c=a+1;c<b;c++)
{
printf("%c : %d, %o, %X\n",c,c,c,c);
}
}

Crashing issue, might be due to a for loop

My program keeps crashing while I run it. I have isolated parts of it (using /**/) to try and figure out what the issue is, and I think it has something to do with the second for loop in my sort function, since isolating that prevents the crashing. However, I've tried fixing it in several different ways (using while/do loops instead, etc), but it manages to keep crashing. Ive also looked at the parameters and how I declared it in main, but I can't see an issue with that. Knowing me, its probably something really dumb ive been missing for hours trying to fix this. Any help would be greatly appreciated
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 5
struct student
{
char name[20];
int hw1, hw2, hw3, ex1, ex2, totalhw, totalex;
float classperc;
char grade;
};
void student_info(struct student s[], int n, int *classex1, int *classex2, int *a, int *b, int *c, int *d, int *f)
{
for (int i = 0; i < n; i++)
{
printf("\n\nPlease enter the student's name:\n");
gets_s(s[i].name, 20);
printf("\nPlease enter the student's homework grades:\n");
scanf("%d %d %d", &(s[i].hw1), &(s[i].hw2), &(s[i].hw3));
printf("\nPlease enter the student's exam scores:\n");
scanf("%d %d", &(s[i].ex1), &(s[i].ex2));
getchar();
s[i].totalhw = s[i].hw1 + s[i].hw2 + s[i].hw3;
s[i].totalex = s[i].ex1 + s[i].ex2;
*classex1 += s[i].ex1;
*classex2 += s[i].ex2;
s[i].classperc = ((float)s[i].totalhw / 1.875) + ((float)s[i].totalex / 3.333);
if (s[i].classperc >= 90)
{
*a = *a + 1;
s[i].grade = 'A';
}
else if (s[i].classperc >= 80)
{
*b = *b + 1;
s[i].grade = 'B';
}
else if (s[i].classperc >= 70)
{
*c = *c + 1;
s[i].grade = 'C';
}
else if (s[i].classperc >= 60)
{
*d = *d + 1;
s[i].grade = 'D';
}
else
{
*f = *f + 1;
s[i].grade = 'F';
}
}
}
void sort(struct student s[], int n)
{
struct student temp;
for (int i = 0; i < SIZE - 1; i++)
{
for (int j = i + 1; j< SIZE; j++)
{
if (strcmp(s[i].name, s[j].name) > 0)
{
temp = s[i];
s[i] = s[j];
s[j] = temp;
}
}
}
for (int i = 0; i < n; i++)
{
printf("\nStudent: %s\nThe Three Homework Scores: %d %d %d\nThe Two Exam Scores: %d %d\n", s[i].name, s[i].hw1, s[i].hw2, s[i].hw3, s[i].ex1, s[i].ex2);
printf("Total Homework Score: %d\nTotal Exam Score: %d\nClass Percentage: %f Grade: %s", s[i].totalhw, s[i].totalex, s[i].classperc, s[i].grade);
// It crashes right before executing this second printf statement (I have no idea why :[)
}
}
void avg_exams(int classex1, int classex2, float *avgex1, float *avgex2)
{
*avgex1 = classex1 / (float)5;
*avgex2 = classex2 / (float)5;
}
void print_classinfo(float avgex1, float avgex2, int a, int b, int c, int d, int f)
{
printf("\n\nThe Average Exam Score for Exam 1 is: %0.2f\nThe Average Exam Score for Exam 2 is: %0.2f\n", avgex1, avgex2);
printf("There were %d A's, %d B's, %d C's, %d D's, %d F's in the class overall\n\n", a, b, c, d, f);
}
void main()
{
struct student s[SIZE];
int a, b, c, d, f , classex1, classex2;
a = b = c = d = f = 0;
classex1 = classex2 = 0;
float classperc, avgex1, avgex2;
student_info( s, SIZE, &classex1, &classex2, &a, &b, &c, &d, &f);
sort(s, SIZE);
avg_exams(classex1, classex2, &avgex1, &avgex2);
print_classinfo(avgex1, avgex2, a, b, c, d, f);
system("PAUSE");
}
Check out your printf() format codes. You can break it into smaller chunks for debugging, to see which portion of the printf() is working unexpectedly.
I don't think the crash is due to your for loops.

Convert Ascii to Binary

I am writing a program where I need to convert Ascii characters to binary and then do a count. I have gotten my code working but it is printing additional information and not necessarily the correct binary. Below is my code as well as the output for a given set of characters. Any assistance would be greatly appreciated!
#include <stdio.h>
#include <stdlib.h>
void binaryPrinter(int digEnd, int value, int * noOfOnes);
void print(char c);
int charToInt(char c)
{
return (int) c;
}
int main()
{
char value;
int result = 1;
while(result != EOF)
{
result = scanf("%c", &value);
if(result != EOF)
{
print(value);
}
}
}
void binaryPrinter(int digEnd, int value, int * noOfOnes)
{
if(value & 1)
{
(*noOfOnes) = (*noOfOnes) + 1;
value = value >> 1;
digEnd--;
printf("1");
}
else
{
value = value >> 1;
digEnd--;
printf("0");
}
if(digEnd == 0)
return;
else
binaryPrinter(digEnd, value, noOfOnes);
}
void print(char c)
{
int count = 0;
printf("The character %c =", c);
binaryPrinter(8, charToInt(c), &count);
printf(" 1's = %d\n", count);
}
Here's a pair of functions:
void printCharAsBinary(char c) {
int i;
for(i = 0; i < 8; i++){
printf("%d", (c >> i) & 0x1);
}
}
void printStringAsBinary(char* s){
for(; *s; s++){
printCharAsBinary(*s);
printf(" ");
}
printf("\n");
}
You can see them in action here: http://ideone.com/3mEVbE. They work by masking out a single bit of each character and printing one at a time.

multikey quicksort crashes

i am writing multikey quicksort,i compiles fine,but when i run ,stops working abnormaly,i think it loops for ever or something like this,how could i fix this?ones again when compile no problem,here is link for it
http://ideone.com/bBtaX
it writes runtime error,here is also code
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
using namespace std;
int min(int a,int b){
return a<=b?a:b;
}
#define swap(a,b){ char *t=x[a];x[a]=x[b];x[b]=t;}
#define i2c(i) x[i][depth]
void vecswap(int i, int j, int n, char *x[])
{
while (n-- > 0) {
swap(i, j);
i++;
j++;
}
}
void ssort1(char *x[],int n,int depth);
void ssort(char *x[],int n)
{
ssort1(x,n,0);
}
void ssort1(char *x[],int n,int depth){
int a,b,c,d,r,v;
if(n<=1)
return ;
a=rand()%n;
swap(0,a);
v=i2c(0);
a=b=1;
c=d=n-1;
for (;;)
{
while(b<=c && (r=i2c(b)-v)<=0){
if (r==0) {
swap(a,b);a++;
}
b++;
}
while(b<=c && (r=i2c(c)-v)>=0){
if (r==0) {
swap(c,d); d--;
}
c--;
}
if (b>c)
break;
swap(b,c);
b++;
c--;
}
r=min(a,b-a);
vecswap(0,b-r,r,x);
r = min(d-c, n-d-1);
vecswap(b, n-r, r, x);
r=b-a;
ssort1(x,r,depth);
if (i2c(r)!=0)
ssort1(x+r,a+n-d-1,depth+1);
r=d-c;
ssort1(x+n-r,r,depth);
}
int main(){
char *s[]={"dato","giorgi","beso","computer","deda","kata","spilo"};
int n=sizeof(s)/sizeof(char);
ssort(s,n);
for (int i=0;i<n;i++)
cout<<s[i]<<" "<<endl;
return 0;
}
This:
int n=sizeof(s)/sizeof(char); /* Would return 28, resulting in out of bounds
on array 's' in subsequent for loop. */
should be:
int n=sizeof(s)/sizeof(char*);
^
A safer way of determining the number of elements in an array is:
int n=sizeof(s)/sizeof(s[0]);

Resources