Why is my code producing a segmentation fault? - c

So im working on this program that is supposed to take the pointer to an array and the array’s size (number of elements in the array)
as arguments, finds the place the index of the outlier, fixes the array in place (that is puts the outlier to a
place it is supposed to be), and returns the old index where the outlier was found. i finished my code but for some reason, somewhere in my main function its telling me there is a segmentation fault, i know its in my main function because it compiled and ran fine when it was just the original code. heres the code;
#include <stdio.h>
long long int fix_sorted_array(double* arr, unsigned long n)
{
double temp;
int i, j;
for ( i = 0; i < n - 1; i ++)
{
if (arr[i] > arr[i + 1])
{
for ( j = i + 1; j > 0; j --)
{
if (arr[j] < arr[j-1])
{
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
return i + 1;
}
}
return -1;
}
int main()
{
int n;
int j;//declared variables
double arr[n];
printf("Enter elements of array : \n");
for ( int i = 0; i < n; i ++)
{
scanf("%lf", &arr[i]);
}
printf("Return index : %lld\n",fix_sorted_array (&arr[n], n));
printf("Array after : \n");
for ( j = 0; j < n; j ++)
{
printf("%.2lf", arr[j]);
}
}

You're passing an address outside the array to the function in this line:
printf("Return index : %lld\n",fix_sorted_array (&arr[n], n));
You want to pass the address of the start of the array, not the end, so it should be:
printf("Return index : %lld\n",fix_sorted_array (arr, n));
You also need to initialize n before you declare the array.
printf("How many numbers? ");
scanf("%d", &n);
double arr[n];

You have never accepted the value of n. Below code might help.
#include <stdio.h>
long long int fix_sorted_array(double* arr, unsigned long n)
{
double temp;
int i, j;
for ( i = 0; i < n - 1; i ++)
{
if (arr[i] > arr[i + 1])
{
for ( j = i + 1; j > 0; j --)
{
if (arr[j] < arr[j-1])
{
temp = arr[j];
arr[j] = arr[j-1];
arr[j-1] = temp;
}
}
return i + 1;
}
}
return -1;
}
int main()
{
int n;
int j;//declared variables
printf("Enter the number of elements in arrays");
scanf("%d",&n); // initialize the values of n
double arr[n];
printf("Enter elements of array : \n");
for ( int i = 0; i < n; i ++)
{
scanf("%lf", &arr[i]);
}
printf("Return index : %lld\n",fix_sorted_array (&arr[0], n)); // Also pass the value of starting index in array i.e. `arr[0]`
printf("Array after : \n");
for ( j = 0; j < n; j ++)
{
printf("%.2lf", arr[j]);
}
}

Related

Sorting an array with duplicate values without modifying the elements, without using secondary array or without using any inbuilt function

So as the question says i am just trying to sort an array with duplicate values.
The array is sorted properly but problem arises when a duplicate value is given to the array
O/P:without duplicate
Enter the size of the array : 5
Enter the 5 elements
7 3 4 8 1
After sorting: 1 3 4 7 8
Original array value 7 3 4 8 1
O/P: with duplicates
5 3 1 1 4
After sorting: 1 3 4 1 3
Original array value 5 3 1 1 4
#include <stdio.h>
void print_sort(int *arr, int size) //function definition
{
int i, j, k, temp, largest = arr[0], smallest = arr[0];
for( i = 1 ; i < size ; i++ )
{
if(arr[i] > largest)
{
largest = arr[i];
}
if(arr[i] < smallest)
{
smallest = arr[i];
}
}
printf("After sorting: ");
for(i = 0; i < size; i++)
{
temp = largest;
printf("%d ", smallest);
for(k = i + 1; k < size; k++)
{
if(arr[i] == arr[k])
{
smallest = arr[i];
break;
}
for(j = 0; j < size; j++)
{
if(arr[j] > smallest && arr[j] < temp)
{
temp = arr[j];
}
}
smallest = temp;
}
}
printf("\n");
printf("Original array value ");
for( i = 0 ; i < size ; i++ )
{
printf("%d ", arr[i]);
}
}
int main()
{
int size, i;
printf("Enter the size of the array : ");
scanf("%d", &size);
int arr[size];
printf("Enter the %d elements\n",size);
for (i = 0; i < size; i++)
{
scanf("%d", &arr[i]);
}
print_sort(arr, size);
}
I understand that it is a specific exercise (homework ?), with no possibility to modify the array not to use an additional array.
This implies that classical sorting algorithms cannot work.
Iteratively searching for the minimum is a possible solution, even if not efficient O(n^2).
To cope with duplicates, it it necessary not only to memorize the current minimum, but also its position.
This is a possible implementation.
#include <stdio.h>
#include <stdlib.h>
void print_sort(int *arr, int size) //function definition
{
int i, j, k, largest = arr[0], smallest = arr[0];
int i_smallest = 0;
for (i = 1; i < size; i++ ) {
if (arr[i] > largest) {
largest = arr[i];
}
if(arr[i] < smallest) {
smallest = arr[i];
i_smallest = i;
}
}
printf("After sorting: ");
for (i = 0; i < size; i++) {
int temp = largest + 1;
int i_temp = -1;
printf("%d ", smallest);
if (i == size-1) break;
for (k = 0; k < size; k++) {
if (arr[k] < smallest) continue;
if (arr[k] == smallest) {
if (k <= i_smallest) continue;
i_temp = k;
temp = smallest;
break;
}
if (arr[k] < temp) {
temp = arr[k];
i_temp = k;
}
}
smallest = temp;
i_smallest = i_temp;
}
printf("\n");
printf("Original array value ");
for( i = 0 ; i < size ; i++ )
{
printf("%d ",arr[i]);
}
}
int main(void) {
int size, i;
printf("Enter the size of the array : ");
if (scanf("%d", &size) != 1) exit(1);
int arr[size];
printf("Enter the %d elements\n",size);
for (i = 0; i < size; i++) {
if (scanf("%d", &arr[i]) != 1) exit(1);
}
print_sort(arr, size);
return 0;
}
Maybe it is easier to insert each read value directly into the sorted Array. So you don't have to sort the array afterwards.
If you want to do it this way, geeksforgeeks.org has nice examples also for C which I already used (https://www.geeksforgeeks.org/search-insert-and-delete-in-a-sorted-array/).
// C program to implement insert operation in
// an sorted array.
#include <stdio.h>
// Inserts a key in arr[] of given capacity. n is current
// size of arr[]. This function returns n+1 if insertion
// is successful, else n.
int insertSorted(int arr[], int n, int key, int capacity)
{
// Cannot insert more elements if n is already
// more than or equal to capacity
if (n >= capacity)
return n;
int i;
for (i = n - 1; (i >= 0 && arr[i] > key); i--)
arr[i + 1] = arr[i];
arr[i + 1] = key;
return (n + 1);
}
/* Driver program to test above function */
int main()
{
int arr[20] = { 12, 16, 20, 40, 50, 70 };
int capacity = sizeof(arr) / sizeof(arr[0]);
int n = 6;
int i, key = 26;
printf("\nBefore Insertion: ");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
// Inserting key
n = insertSorted(arr, n, key, capacity);
printf("\nAfter Insertion: ");
for (i = 0; i < n; i++)
printf("%d ", arr[i]);
return 0;
}

Arranging columns in a matrix lexicographically

I've been trying to sort columns in a matrix (the dimensions are m,n <= 10) via the lexicographical order (if the columns share the same element, then we compare the elements in the row beneath etc.) with some additional conditions. I need to use functions to print the matrix, input random integers up to 5 as its elements and finally arrange the matrix. I think I got the printing and random inputs correctly but I can't figure out the sorting. Plus I can't use global variables which I have no idea how to do, since I haven't been shown. An example matrix would be :
#include <stdio.h>
#include <stdlib.h>
int main()
{
int m, n;
int mat[10][10];
void print_matrix()
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
void random_int()
{
int i, j;
srand((unsigned)time(NULL));
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
mat[i][j] = rand() % 5;
}
}
}
void arrange()
{
int i, j, k, a;
for (j = 0; j < n; ++j)
{
for (i = 0; i < m; ++i)
{
for (k = i + 1; k < m; ++k)
{
if (mat[i][j] < mat[k][j])
{
a = mat[i][j];
mat[i][j] = mat[k][j];
mat[k][j] = a;
}
}
}
}
}
printf("Input the number of rows : ");
scanf("%d", &m);
printf("Input the number of columns: ");
scanf("%d", &n);
random_int(mat[m][n]);
print_matrix(mat[m][n]);
arrange(mat[m][n]);
print_matrix(mat[m][n]);
return 0;
}
Try this solution(will work for input 0-8 only), also used global variables:
There have multiple solutions. but is the easiest one.
I have converted each of the columns as an integer value. then bubble sorted the integers. After sorting. I have then converted the integer value to digits. (You have to know how to convert individual digits to multiple digit integer and multiple digit integers to single-digit.
Note I have added one(1) with each digit. Because the input can be zero(0). if you convert 0 0 2 1 to an integer will be only 21. the first two digits lost. So I have added 1. so 0 0 2 1 will be converted to 1132. I have done (added 1) for each input(deducted 1 after sorting). so it will not affect other inputs. Be careful input have to be from(0 to 8)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int m, n;
int mat[10][10];
int generatedNumber[10];
void print_matrix()
{
printf("The matrix is:\n");
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
void random_int()
{
int i, j;
srand((unsigned)time(NULL));
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
mat[i][j] = rand() % 5;
}
}
}
void arrange()
{
int i, j, k, a;
for (j = 0; j < n; ++j)
{
int number = 0;
for (i = 0; i < m; ++i)
{
number = number * 10 + mat[i][j] + 1;///Adding one for avoiding zero(0)
}
generatedNumber[j] = number;
}
for(i = 0; i < n; i++)
{
for(j = 0; j < n-i-1; j++)
{
if( generatedNumber[j] > generatedNumber[j+1])
{
// swap the elements
int temp = generatedNumber[j];
generatedNumber[j] = generatedNumber[j+1];
generatedNumber[j+1] = temp;
}
}
}
for(i = 0; i < n; i++)///columwise
{
int generatedColumnvalue = generatedNumber[i];
for(j = m -1; j>= 0; j--)///row wise and fro last vaue to first
{
mat[j][i] = (generatedColumnvalue%10)-1;///removing extra added 1
generatedColumnvalue/=10;
}
}
}
int main()
{
printf("Input the number of rows : ");
scanf("%d", &m);
printf("Input the number of columns: ");
scanf("%d", &n);
random_int();
print_matrix();
arrange();
print_matrix();
return 0;
}

array manipulation question on hackerrank

My code shows segmentation fault on hackerrank.What will happen if I use long long int?
Here is the link https://www.hackerrank.com/challenges/crush/problem?isFullScreen=true
My code is:
#include <stdio.h>
int main()
{
int n, m;
scanf("%d%d", &n, &m);
int queries[m][3];
for (int i = 1; i <= m; i++) {
scanf("%d", &queries[i][1]);
scanf("%d", &queries[i][2]);
scanf("%d", &queries[i][3]);
}
int a[n];
for (int i = 1; i <= n; i++)
a[i] = 0;
for (int i = 1; i <= m; i++) {
for (int j = queries[i][1]; j <= queries[i][2]; j++)
a[j] = a[j] + queries[i][3];
}
int max;
max = 0;
for (int i = 1; i <= n; i++) {
if (max < a[i])
max = a[i];
}
printf("%d", max);
return 0;
}
Array index out of bounds at .
a[j]=a[j]+queries[i][3];
because Array index 3 is past the end of the array (which contains 3 elements) thus 2 is the last index.
and when using the for loops to access the array you might need to start from 0
Code
#include<stdio.h>
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int queries[m][3];
for( int i=0;i<m;i++)
{
scanf("%d",&queries[i][0]);
scanf("%d",&queries[i][1]);
scanf("%d",&queries[i][2]);
}
int a[n];
for(int i=0;i<n;i++)
a[i]=0;
for(int i=0;i<m;i++)
{
for(int j=queries[i][0];j<=queries[i][1];j++)
a[j]=a[j]+queries[i][2];
}
int max;
max=0;
for(int i=0;i<n;i++)
{
if(max<a[i])
max=a[i];
}
printf("%d",max);
return 0;
}
You have array index out of bounds error at this line:
a[j] = a[j] + queries[i][3];
What value can i take?
To avoid similar errors in the future you may want to consider usage of tools for static code analysis. For example, cppcheck is a free and open source tool that can detect this error:
stackoverflow/c-issue.c:23:34: error: Array 'queries[2147483648][3]' accessed
at index queries[*][3], which is out of bounds.
[arrayIndexOutOfBounds]
a[j] = a[j] + queries[i][3];
In every loop you are passing boundaries of your array which will cause undefined behavior.
when you declare int arr [num] , if you access arr[x] while x=>num , you are passing boundaries of your array and that will cause undefined behavior , which means you can't predict what will happen.
look
int main()
{
int n, m;
scanf("%d%d", &n, &m);
int queries[m][3];
for (int i = 0; i < m; i++) {
scanf("%d", &queries[i][0]);
scanf("%d", &queries[i][1]);
scanf("%d", &queries[i][2]);
}
int a[n];
for (int i = 0; i < n; i++)
a[i] = 0;
for (int i = 0; i < m; i++) {
for (int j = queries[i][0]; j <= queries[i][1]; j++)
a[j] = a[j] + queries[i][2];
}
int max;
max = 0;
for (int i = 0; i < n; i++) {
if (max < a[i])
max = a[i];
}
printf("%d", max);
return 0;
}

Copying elements from an array to another one and counting the number of a character in C

I'm new to C, so I apologize for asking silly questions.
I need to copy certain elements from an array to another one, but I can't make it work and get random numbers instead. In this case I need all the elements after the smallest one from the first array to be copied to the second one.
The other thing I can't figure out is a function that counts how many times a certain symbol is used. I need to find the number of times I've used the biggest odd digit in an array.
Here's the code, I've made so far. I hope you understand most of it:
#include <stdio.h>
#define DIM 100
int enter (int x[]);
int min (int x[], int y[], int n);
int sort (int x[], int n);
void print (int x[], int n);
//=============================================
int main () {
int a[DIM], b[DIM], n, i;
n = enter (a);
printf("The smallest element in the first array: %d.\n The smallest element in the second array: %d.\n", min (a, b, n));
printf("%d\n", sort (b, n));
for (i = 0; i < n; i++)
printf ("%d ", b[i]);
printf ("\n");
system("pause");
return 0;
}
//===========================================================
int enter (int x[]) {
int i, n;
do {
printf ("Enter number of elements in array: ");
scanf ("%d", &n);
}
while (n < 1 || n > DIM);
printf ("Enter %d elements:\n", n);
for (i = 0; i < n; i++)
scanf ("%d", &x[i]);
return x[i], n;
}
int min (int x[], int y[], int n) {
int minimum, i, j=0, p;
minimum = x[0];
for ( i = 1 ; i < n ; i++ ) {
if ( x[i] < minimum ) {
minimum = x[i];
p = i+1;
}
}
for (i = p+1; i<n; i++ && j++) {
x[i] = y[j];
}
return minimum;
}
int sort (int x[], int n) {
int i, j, a;
for (i = 0; i < n; ++i) {
for (j = i + 1; j < n; ++j) {
if (x[i] > x[j]){
a = x[i];
x[i] = x[j];
x[j] = a;
}
}
}
printf("Elements from array in ascending order: \n");
for (i = 0; i < n; ++i)
printf("%d\n", x[i]);
return x[i];
}
I need to find the number of times I've used the biggest odd digit in
an array.
Fist sort your array start at the end and find the biggest odd number. You can find a odd number by number%2==1. Finally count equal numbers:
// sort the array
sort(b, n); // sort function from your questions code
// find the biggest odd number
int i = n-1;
while ( i >= 0 && b[i]%2 == 0 )
{
i --;
}
// count the biggest odd number
count = 0;
int j = i;
while ( j >= 0 && b[i]==b[j] ) // note first time i==j !
{
count ++;
j --;
}
If you don't want to sort your array use this:
// find the biggest odd number
int oddInx = -1;
for ( int i = 0; i < n; i++ )
{
if ( b[i]%2 == 1 && ( oddInx < 0 || b[i] > b[oddInx] ) )
oddInx = i;
}
// count the biggest odd number
count = 0;
if ( oddInx >= 0 )
{
for ( int i = 0; i < n; i++ )
{
if ( b[i] == b[oddInx] )
count ++;
}
}

Sorting array based on index of minimum value?

I'm currently trying to learn C, and the exercise I found online has me creating a function that returns the index of the smallest value in an array. This is my function:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = 0;
for (int index = i; index < j; index++){
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}
i and j are the lower and upper bound numbers the function should look in. For example, if i is 4 and j is 8, that means the function will return the index of the smallest value between indices 4 and 8.
Here is my main function:
#include <stdio.h>
int main(){
int numbers[10];
int user_input = 0;
for (int i = 0; i < 10; i++){
printf("Please enter a number: ");
scanf_s("%d", &user_input);
numbers[i] = user_input;
}
for (int i = 0; i < 10; i++){
int index_of_min_value = return_index_of_minimum(numbers, i, 10);
int old_num = numbers[index_of_min_value];
int new_num = numbers[i];
numbers[index_of_min_value] = new_num;
new_array[i] = old_num;
}
for (int i = 0; i < 10; i++){
printf("%d\n", new_array[i]);
}
}
The user would first enter a bunch of numbers and that would populate the array with the user's values. The idea is to use return_index_of_minimum to return the index of the smallest item in an array, and then set that equal to numbers[0] with a for loop, and then numbers[1], and then so on. old_num is the lowest number in the array, at its previous index. Here, I'm trying to swap that minimum value with whatever is at numbers[i] However, when I'm done sorting through the entire array, and am printing it out, I see that 10 (when the user enters 1-10 randomly for values) is at index 0, and then the rest of the numbers are in order. Does anybody see what is wrong here?
Here is a fix:
int return_index_of_minimum(int A[10], int i, int j){
int minimum_value = A[i];
int index_to_return = i;
...
}
Unfortunately this code doesn't have protection of invalid arguments, but otherwise this is an answer you've been looking for.
The reason is in call index_of_minimum(a, 9, 10): the loop performs only one iteration for index = 9, and because the minimum value is already initialized to value a[9], the index_to_return is not updated due to condition check.
This is a different approach that doesn't have same issue:
int return_index_of_minimum(int A[10], int i, int j){
/* assuming i < j */
int minimum_value = A[i];
int index_to_return = i; /* First element is a candidate */
for (int index = i + 1; index < j; index++){
/* Iterate from second element */
if (A[index] < minimum_value){
minimum_value = A[index];
index_to_return = index;
}
}
return index_to_return;
}
I believe there is an error in your return_index_of_minimum function.
int index_to_return = 0;
The problem lies I think here as the value of index_to_return will stay 0 if you call return_index_of_minimum(numbers, 5, 10); and that numbers[5] if the actual minimum.
However why not use a simple bubble-sort like the one implemented here
/*
* C program to sort N numbers in ascending order using Bubble sort
* and print both the given and the sorted array
*/
#include <stdio.h>
#define MAXSIZE 10
int main(void)
{
int array[MAXSIZE];
int i, j, num, temp;
printf("Enter the value of num \n");
scanf("%d", &num);
printf("Enter the elements one by one \n");
for (i = 0; i < num; i++)
{
scanf("%d", &array[i]);
}
printf("Input array is \n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
/* Bubble sorting begins */
for (i = 0; i < num; i++)
{
for (j = 0; j < (num - i - 1); j++)
{
if (array[j] > array[j + 1])
{
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
printf("Sorted array is...\n");
for (i = 0; i < num; i++)
{
printf("%d\n", array[i]);
}
}

Resources