segmentation fault in this code - c

#include <math.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
void sort(int a[], int n)
{
int i, j;
for (i = 0; i < n - 1; i++)
for (j = i; j < n - 1; j++)
if (a[j] > a[j + 1])
a[j] = a[j + 1] - (a[j + 1] = a[j]);
}
int call(int i, int hit, int t, int h[], int n, int count)
{
static int max = 0;
if (t <= 0)
{
if (count > max)
max = count;
return max;
}
if (h[i] > 0)
{
h[i] -= hit;
if (h[i] <= 0)
count++;
max = call((i + 1) % n, hit, t - 1, h, n, count);//this is line where illegal access to memory is being made
count--;
h[i] += hit;
}
max = call((i + 1) % n, hit, t, h, n, count);
return max;
}
int getMaxMonsters(int n, int hit, int t, int h[]) {
sort(h, n);
int m = call(0, hit, t, h, n, 0);
return m;
}
int main() {
int n;
int hit;
int t;
scanf("%d %d %d", &n, &hit, &t);
int h[100000];
for (int h_i = 0; h_i < n; h_i++) {
scanf("%d", &h[h_i]);
}
int result = getMaxMonsters(n, hit, t, h);
printf("%d\n", result);
return 0;
}
This code computes in the maximum number of monsters that can be killed.
n is no. of monsters
hit is hit value
h[] contains health value of each monster
t is the total time available
So, the maximum number of monsters have to be killed in t seconds and and only one monster per second.
I am getting segmentation fault for illegal access of memory. Unable to understand how am I crossing the array limits.

Ask your debugger or use Valgrind.
it automatically detects memory management bugs. it also profiles your program in detail.
it is too simple to use Valgrind.

Related

Can't figure out how to change my code to solve a recursive problem

Print k-element subsets of an n element set (In essence n choose k)
represent each subset as an array and skip B[0].
For example [0 1 0 1] means {1,3} to print.
I believe my main problem is in my printSubsets() function because I am calling the method twice.
But it looks like it can't do that; it ignores the "2" in the index until the very end of the program.
Code
#include <stdio.h>
#include <stdlib.h>
void printSet(int B[], int n) {
for(int j = 1; j <= n; j++) {
printf("%d", B[j]);
}
}
void printSubsets(int B[], int n, int k, int i) {
if(i <= n) {
if(k == 0) {
printSet(B, n);
printf("\n");
}else{
B[i] = 1; //print 1 in the index of interest and recurse
printSubsets(B, n, k-1, i++);
B[i] = 2; //print 2 as a holder to ignore that index
printSubsets(B, n, k, i++);
}
}
}
int main(){
int n;
int k;
scanf("%d %d", &n, &k);
int B[101];
printSubsets(B, n, k, 1);
return EXIT_SUCCESS;
}

I have a problem with "The 3n+1 problem".when i debug it

I've tried to solve "The 3n+1" problem.
When I debug my code it stuck at line 12, calculation function.
"According to Collatz conjecture, j should converge to 1."
Main file
#include "input_output.h"
#include <stdlib.h>
int main() {
int i=0, j=0;`
int *num;
int maxCycle;
int length;
input(&i, &j);
length = j - i + 1;
num = (int*)malloc(sizeof(int)*(j - i+1));
here is the problem code
while (i <= j) {
calculate(j, num);//<- it stuck at here when i dubug it.
j--;
num++;
}
maxCycle = findMax(length, num);
output(maxCycle);
return 0;
}
source file
#include <stdio.h>
#include "input_output.h"
#pragma warning (disable:4996)
void input(int *i, int *j) {
scanf("%d %d", i,j);
}
void calculate(int j, int* num) {
while (j > 1) {
if (j % 2 == 0) {
j = j / 2;
*num++;
}
if (j % 2 == 1) {
j = j * 3 + 1;
*num++;
}
}
}
int findMax(int length, int * num){
int max = 0;
int idx = 0;
while (idx < length) {
if (*num > max) max = *num;
idx++;
num++;
}
return max;
}
void output(int maxout) {
printf("%d", maxout);
}
Header
#ifndef __input_output_H__
#define __input_output_H__
void input(int *i, int *j);
void calculate(int j,int *num);
int findMax(int length, int* num);
void output(int maxout);
#endif __input_output_H__
I think header seems no problem and also main file.
is there any problem with my source file?
I wonder why debugger stuck at there...
Your loop never ends: you reach j == 1, yet you continue to apply 3n + 1, which makes you go back to 4, and therefore you are in a loop forever:
1 -> 4 -> 2 -> 1 -> ...
By the way, this:
*num++;
is not doing what you think it is doing. You are incrementing the pointer, and then accessing the value (which is not used). So it is as if you had written:
num++;
You should have written (*num)++.
The problem is at j = j * 3 + 1;, 'j' keeps on increasing if 'j' is greater than 1 and odd. So it hangs at calculate(int j,int *num) as the while loop inside it runs infinitely (j value will reset after a while).
Edit:
I have accumulated all the corrections and have added the code:
main.c :
#include "input_output.h"
#include <stdlib.h>
int main()
{
int i=0, j=0;
int *num,*ori; //New pointer required to remember the start position of num
int maxCycle;
int length;
input(&i, &j);
length = j - i + 1;
num = (int*)calloc((size_t)(j-i+1),sizeof(int));
ori=num;
while (i <= j)
{
calculate(j, num);
j--;
num++;
}
num=ori;
maxCycle = findMax(length, num);
num=ori;
output(maxCycle);
return 0;
}
input_output.h :
#ifndef INPUT_OUTPUT_H
#define INPUT_OUTPUT_H
void input(int *i, int *j);
void calculate(int j,int *num);
int findMax(int length, int* num);
void output(int maxout);
#endif
input_output.c :
#include <stdio.h>
#include "input_output.h"
void input(int *i, int *j) {
printf("Enter the i & j:\n");
scanf("%d%d",i,j);
printf("Values entered:\ni: %d\nj: %d",*i,*j);
}
void calculate(int j, int* num) {
while (j > 1) {
if (j==1)
break;
if (j % 2 == 0) {
j = j / 2;
(*num)++;
}
else{
j = j * 3 + 1;
(*num)++;
}
}
printf("\nLength Value: %d\n",*num);
}
int findMax(int length, int * num){
int max = 0;
int idx = 0;
printf("\nLength Values:\n");
while (idx < length) {
printf("%d ",*num);
if (*num > max)
max = *num;
idx++;
num++;
}
return max;
}
void output(int maxout) {
printf("\nResult: %d", maxout);
}
Compile in linux using: gcc input_output.c main.c -Wall -Wextra -pedantic -Wconversion -std=gnu11 -o collatz
For further clarification please comment.

Quick Sort Array Random Number Generator Nothing Printed Error

I have this C code that creates an array with 100 random numbers and I want to sort it using quick sort, but it always gives a Segmentation fault error.
Here is the code:
#define MAX 100
int a[MAX];
void quick_sort(double *x, int l, int r) {
int l1, r1;
if (l < r) {
l1 = l;
r1 = r;
do {
while (l1 < r && x[l1 - 1] <= x[l - 1]) {
l1++;
}
while (l < r1 && x[r1 - 1] >= x[l - 1]) {
r1--;
}
if (l1 < r1) {
swap(&x[l1 - l], &x[r1 - 1]);
}
} while (l1 < r1);
swap(&x[l - 1], &x[r1 - 1]);
quick_sort(x, l, r1 - 1);
quick_sort(x, r1 + 1, r);
}
}
void printArray(int a[], int size) {
int i;
for (i = 0; i < size; i++)
printf("%d ", a[i]);
printf("\n");
}
int main() {
int i = 1;
int a_size = sizeof(a) / sizeof(a[0]);
srand((unsigned int)time(NULL));
for (i = 0; i < MAX; i++) {
a[i] = rand() % 501;
}
quick_sort(a, 0, a_size);
printArray(a, a_size);
}
The error is that nothing prints when I run the program.
Can someone help me with the problem?
There are many problems in your code:
You do not include <stdio.h>, <stdlib.h>, nor <time.h>.
Your quick_sort function expects a pointer to an array of double, yet you pass an array of int.
The code for function swap() is not posted.
Your implementation of the Quick Sort algorithm in function quick_sort is flawed:
you should not scan slices of size 1, use (r - l > 1).
You cannot use x[l - 1] as pivot, it is not even part of the slice to be sorted. Furthermore, you should extract the pivot from the array before the swapping phase as it may move.
You should not name a variable l, it looks too close to 1 and you do make the mistake here: swap(&x[l1 - l], &x[r1 - 1]);
You should initialize l1 and r1 such that you do not need to subtract 1 in so many places, it leads to confusion and erroneous code.
Study the algorithms from the Wikipedia article and translate one to C.
Here is a corrected version:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX 100
void swap(int *a, int *b) {
int x = *a;
*a = *b;
*b = x;
}
// Quick Sort using Hoare's original partition scheme
void quick_sort(int *x, int l, int r) {
if (l < r) {
int pivot = x[l];
int l1 = l - 1;
int r1 = r;
for (;;) {
while (x[++l1] < pivot)
continue;
while (x[--r1] > pivot)
continue;
if (l1 < r1) {
swap(&x[l1], &x[r1]);
} else {
break;
}
}
quick_sort(x, l, r1 + 1);
quick_sort(x, r1 + 1, r);
}
}
void printArray(int a[], int size) {
for (int i = 0; i < size; i++) {
printf("%d ", a[i]);
}
printf("\n");
}
int main(void) {
int a[MAX];
int a_size = sizeof(a) / sizeof(a[0]);
srand((unsigned int)time(NULL));
for (int i = 0; i < MAX; i++) {
a[i] = rand() % 501;
}
quick_sort(a, 0, a_size);
printArray(a, a_size);
return 0;
}

Parallelization of Combination

I have got a piece of code that prints the combination of M number From N (nCm);
As it is a recursion, it works very slow when N is large.
#include <stdio.h>
#include <stdlib.h>
#define N 80
#define M 4
int result[M]= {0}; // THE ARRAY THAT SAVE THE RESULT OF ONE COMBINATION
int queue[N] = {0};
int top = 0;
void comb(int* input,int s, int n, int m)
{
if (s > n)
return ;
if (top == m)
{
for (int i = 0; i < m; i++)
{
result[i] = queue[i];
printf("%d\n", queue[i]);
}
}
queue[top++] = input[s];
comb(input,s+1, n, M);
top--;
comb(input,s+1, n, M);
}
int main()
{
int array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,
73,74,75,76,77,78,79,80};
printf("\ncombination():\n");
comb(array,0, N, M);
printf("\n");
}
I would like to know if there is any space for improvement in the algorithm above?
if possible, can I use openMP ?
Thanks
To me your code was even giving the desired output. see
I have changed
printing format each combination was not good enough.
repeated combinations. (note: else part of if statement added).
reduced 2 recursive call with a loop and a recursive call. (Less space.)
The required code is:
#include <stdio.h>
#include <stdlib.h>
#define N 20
#define M 6
int result[M]= {0}; // THE ARRAY THAT SAVE THE RESULT OF ONE COMBINATION
int queue[N] = {0};
int top = 0;
void comb(int* input,int s, int n, int m)
{
if (s > n)
return ;
if (top == m)
{
printf("\n");
for (int i = 0; i < m; i++)
{
result[i] = queue[i];
printf("%d ", queue[i]);
}
}else{
for(int ss=s;ss<n;ss++){
queue[top++] = input[ss];
comb(input,ss+1, n, m);
top--;
}
//comb(input,s+1, n, m);
}
}
int main()
{
int array[] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,
27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,
50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,
73,74,75,76,77,78,79,80};
printf("\ncombinations():\n");
comb(array,0, N, M);
printf("\n");
}

QuickSort Algorithm Number of Comparisons

I have been taking a class at Coursera and we had an assignment which was to count the number of comparisons QuickSort does on a 10,000 size array a numbers.
#include <stdio.h>
#define SIZE 10000
int ComparsionCount = 0;
void swap(int a[], int i, int j) {
int temp = a[j];
a[j] = a[i];
a[i] = temp;
}
int partition(int a[], int l, int r){
int p = a[l];
int i = l + 1;
int j;
for (j = l + 1; j <= r; j++) {
if (a[j] < p) {
swap(a, j, i);
i++;
}
}
swap(a, l, i - 1);
return (i - 1);
}
void add(int i) {
ComparsionCount += i;
}
int QuickSort(int a[], int l, int r){
int pivot;
if (r > 1) {
add(r - 1);
pivot = partition(a, l, r);
QuickSort(a, l, pivot - 1);
QuickSort(a, pivot + 1, r);
}
return pivot;
}
int main() {
FILE *fr;
int arr[SIZE];
int i = 0;
int elapsed_seconds;
char line[80];
fr = fopen("QuickSort.txt", "r");
while (fgets(line, 80, fr) != NULL)
{
/* get a line, up to 80 chars from fr. done if NULL */
sscanf (line, "%ld", &elapsed_seconds);
/* convert the string to a int */
arr[i] = atoi(line);
i++;
}
fclose(fr); /* close the file prior to exiting the routine */
printf("%d\n",QuickSort(arr,0,SIZE-1));
}
I am getting an segmentation error. I have identified that the problem lies in two recursive calls of QuickSort.
I have no idea of how to solve this problem,your help would be appreciated a lot
Thanks in advance.
I think you should add the code in the partition function like this:
for (j = l + 1; j <= r; j++) {
count++;
if (a[j] < p) {
...
}
Note: count is a global variable initialized to 0.

Resources