Recursive selectionsort algorithm exiting, why? - c

I got the task to write a recursive selectionsort algorithm, which i did.
The algorithm works fine until i increase the array size to more than 150 elements.
After i increased the elements, the algorithm stops working and exits with a "strange" (-1073741571 (0xC00000FD)) exit code.
I guess that somewhere i exceed the data range. But even after staring an hour at my code i cannot find where. Using the debugging fuction does not give me any hint.
Can someone help me why this code isn't working with more than 150 elements?
#include <stdio.h>
#include <string.h>
#include <limits.h>
#define MAX 500
// print the array and count the number of reoccurring characters and print it.
void ausgabe(int *array, size_t size)
{
int i;
int prev_char = INT_MAX, cur_char, count = 0;
for (i = 0; i < size; i++)
{
cur_char = array[i];
if (cur_char == prev_char)
{
printf("%c", array[i]);
prev_char = cur_char;
count++;
}
else
{
printf(" Count = %i\n%c", count, array[i]);
prev_char = cur_char;
count = 0;
}
}
printf(" Count = %i", count);
}
//Fill the array with characters from A to Z and start over
void fill_field(int *array, size_t size)
{
int i, j = 0;
for (i = 0; i < size; i++)
{
if ( j > 25)
j = 0;
array[i] = 65 + j++;
}
}
//Recursive selectionsort algorithm.
void selection_sort(int *source, size_t size)
{
static int min = INT_MAX, position = 0, start_pos = 0, temp, found;
if ( position < size)
{
if (min > source[position])
{
min = source[position];
found = position;
}
position++;
selection_sort(source, size);
}
else
{
temp = source[start_pos];
source[start_pos] = min;
source[found] = temp;
position = start_pos + 1;
start_pos++;
min = INT_MAX;
if ( position < size )
selection_sort(source, size);
}
}
int main(void)
{
int array[MAX];
fill_field(array, MAX);
ausgabe(array, MAX);
selection_sort(array, MAX);
ausgabe(array, MAX);
return 0;
}

Related

"assignment makes integer from pointer without a cast"?

I'm really new to this. I've never done anything like this so I'm having issues with this code. I was given a template to write my code in separate functions like this, although I added the findPos one myself. I'm getting the "assignment makes integer from pointer without a cast" warning and also my max, min, sum, avg, and position of max and min are obviously not coming out to the right numbers. I was just wondering if anyone can lead me in the right direction.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int findMin(int arr[], int size);
int findMax(int arr[], int size);
int findSum(int arr[], int size);
int findPos(int arr[], int size);
int size;
int i;
int max;
int min;
int avg;
int sum;
int pos;
int main()
{
srand(time(0));
printf("Enter an integer: ");
scanf("%d", &size);
int arr[size];
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
avg = sum / size;
printf("max:%7d\tpos:%d\t\n", max, pos);
printf("min:%7d\tpos:%d\t\n", min, pos);
printf("avg:%7d\n", avg);
printf("sum:%7d\n", sum);
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
return 0;
}
int findMin(int arr[], int size)
{
min = arr[0];
for (i = 0; i < size; i++) {
if (arr[i] < min) {
min = arr[i];
}
}
return min;
}
int findMax(int arr[], int size)
{
max = arr[0];
for (i = 0; i < size; i++) {
if (arr[i] > max) {
max = arr[i];
}
}
return max;
}
int findSum(int arr[], int size)
{
sum = 0;
for (i = 0; i < size; i++) {
sum = sum + arr[i];
}
return sum;
}
int findPos(int arr[], int size)
{
for (i = 0; i < size; i++) {
pos = i;
}
return pos;
}
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
You're assigning function pointer, not return value, to integer variable. You have to do something like max = findMax(arr, size). Also in that case, you should assign values to arr before calling it.
There are a couple of issues with the code. Let me iterate through the same
Populating Data in Created Array
Since the data has to present the created array before performing any operations,
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
this snippet should be reordered and moved above the function calls and just after the int arr[size];
Function Calls
All your functions, namely findMax,findMin,findPos,findSum is expecting two parameters
arr - array you have created
size - the size value read from scanf()
Assuming you want to store the return value from the function in the main int variables max,min,pos,sum,avg
the statements
max = findMax;
min = findMin;
pos = findPos;
sum = findSum;
should be replaced with function calls like
max = findMax(arr, size);
min = findMin(arr, size);
pos = findPos(arr, size);
sum = findSum(arr, size);
The Final Main code will be
int main()
{
srand(time(0));
printf("Enter an integer: ");
scanf("%d", &size);
int arr[size];
printf("\n");
printf(" Pos : Val\n");
printf("-------------\n");
for (i = 0; i < size; i++) {
arr[i] = (rand() % 1001);
printf("%4d :%6d\n", i, arr[i]);
}
max = findMax(arr, size);
min = findMin(arr, size);
pos = findPos(arr, size);
sum = findSum(arr, size);
avg = sum / size;
printf("max:%7d\tpos:%d\t\n", max, pos);
printf("min:%7d\tpos:%d\t\n", min, pos);
printf("avg:%7d\n", avg);
printf("sum:%7d\n", sum);
return 0;
}

I have to arrange the elements in this array from greatest to smallest using 2 methods, but the output is completely different

Here is the code
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int IndexOfMaxInRange(int ra[], int first, int last)
{
int index = first;
int max = ra[first];
for(int i = first+1; i < last; i++)
{
if(ra[i] > max)
{
index = i;
}
}
return index;
}
void SwapElement(int ra[], int iOne, int iTwo)
{
int temp = ra[iOne];
ra[iTwo] = ra[iOne];
ra[iOne] = temp;
}
void SortArray(int ra[],int length)
{
for(int i = 0; i < length; i++)
{
SwapElement(ra, i, IndexOfMaxInRange(ra, i, (length-1)));
}
}
int main(void)
{
int ra[5] = {2,5,8,3,4};
int length = sizeof (ra) / sizeof (ra[0]);
SortArray(ra, length);
for(int i = 0; i < length; i++)
{
printf("%d ", ra[i]);
}
return(EXIT_SUCCESS);
}
I am supposed to arrange the elements from greatest to smallest, but my output is: "2 5 5 2 4"
I know I am doing something wrong, but I can't put my eye on it, thanks in advance for all the feedback.
First of all, the swap was incorrect, you lost ra[iTwo] in the process. Change to
void SwapElement(int ra[], int iOne, int iTwo)
{
int temp = ra[iOne];
ra[iOne] = ra[iTwo];
ra[iTwo] = temp;
}
Second error is that you are not updating the current max in IndexOfMaxInRange
if(ra[i] > max)
{
max = ra[i];
index = i;
}
Now it should work.

getting an error while trying to free malloc

So I have been tasked from school with writing a function that gets an int size parameter, an array of integers and an int flag, and returns an array of pointers, that holds pointers to the cells of the original int array in a sorted manner (ascending if flag==1, else descending).
I wrote it basically on the principle of merge sort, but for some reason I am getting a runtime error that occurs when the program tries to execute line 123 (free a temp int** array)
any idea why it happens and if its fixable?
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 100
int **pointerSort(int *arr, unsigned int size, int ascend_flag);
void ptrMerge(int arr[], int start, int mid, int end, int *ptrArr[], int flag);
void pmergeSort(int arr[], int start, int end, int *ptrArr[], int flag);
void main() {
unsigned int size, i;
int arr[SIZE];
int **pointers;
int ascend_flag;
printf("Please enter the number of items:\n");
scanf("%u", &size);
for (i = 0; i < size; i++)
scanf("%d", &arr[i]);
scanf("%d", &ascend_flag);
pointers = pointerSort(arr, size, ascend_flag);
printf("The sorted array:\n"); //Print the sorted array
//printPointers(pointers, size);
for (i = 0; i < size; i++)
printf("d%\t%d", *pointers[i], pointers[i]);
free(pointers);
}
int **pointerSort(int *arr, unsigned int size, int ascend_flag) {
int **sortedArr;
sortedArr = (int**)malloc(size * sizeof(int*));
pmergeSort(arr, 0, size - 1, sortedArr, ascend_flag);
return sortedArr;
}
void pmergeSort(int arr[], int start, int end, int *ptrArr[], int flag) {
if (start < end) {
int mid = (start + end) / 2;
pmergeSort(arr, start, mid, ptrArr, flag);
pmergeSort(arr, mid + 1, end, ptrArr, flag);
ptrMerge(arr, start, mid, end, ptrArr, flag);
}
}
void ptrMerge(int arr[], int start, int mid, int end, int *ptrArr[], int flag) {
int i, k = 0;
int p = start, q = mid + 1;
int **tempArr;
tempArr = (int**)malloc((end - start + 1) * sizeof(int*));
for (i = start; i <= end; i++) {
if (arr[p] < arr[q]) {
tempArr[k] = &arr[p];
k++;
p++;
} else { //(arr[p] > arr[q])
tempArr[k] = &arr[q];
k++;
q++;
}
}
while (p <= mid) {
tempArr[k] = &arr[p];
k++;
p++;
}
while (q <= end) {
tempArr[k] = &arr[q];
k++;
p++;
}
if (flag == 1) {
for (i = 0; i < k; i++)
ptrArr[start] = tempArr[i];
start++;
}
} else {
for (i = k - 1; i >= start; i--) {
ptrArr[start] = tempArr[i];
start++;
}
}
for (i = 0; i < k; i++)
printf("%x\t%d\n", ptrArr[i], *ptrArr[i]);
printf("\n");
free(tempArr);
}
You get a segmentation fault because the ptrMerge function corrupts the memory by writing past the end of the tempArr allocated array.
The first loop iterates end - start + 1 times, potentially accessing arr beyond the end of the slices.
The loop continues until p >= mid and q >= end, writing to tempArr[k] with k greater or equal to the number of elements allocated with malloc().
The logic is flawed: you compare the elements of arr at offsets p and q instead of indirecting through the array ptrArr.
Here is a modified version:
int **pointerSort(int *arr, int size, int ascend_flag) {
int **sortedArr = (int**)malloc(size * sizeof(int*));
for (int i = 0; i < size; i++) {
sortedArr[i] = &arr[i];
}
pmergeSort(sortedArr, 0, size - 1, ascend_flag);
return sortedArr;
}
void pmergeSort(int *ptrArr[], int start, int end, int flag) {
if (start < end) {
int mid = start + (end - start) / 2;
pmergeSort(ptrArr, start, mid, flag);
pmergeSort(ptrArr, mid + 1, end, flag);
ptrMerge(ptrArr, start, mid, end, flag);
}
}
void ptrMerge(int *ptrArr[], int start, int mid, int end, int flag) {
int i, k, n = end - start + 1;
int p = start, q = mid + 1;
int **tempArr = (int**)malloc(n * sizeof(int*));
for (k = 0; k < n; k++) {
if (p <= mid && (q >= end || *ptrArr[p] <= *ptrArr[q])) {
tempArr[k] = ptrArr[p++];
} else {
tempArr[k] = ptrArr[q++];
}
}
if (flag == 1) {
for (k = 0; k < n; k++)
ptrArr[start + k] = tempArr[k];
}
} else {
for (k = 0; k < n; k++) {
ptrArr[end - k] = tempArr[k];
}
}
free(tempArr);
}
Also note that main() must be defined with a return type int and the loop that prints the values is broken. It should read:
for (i = 0; i < size; i++)
printf("%d\t", *pointers[i]);
printf("\n");
So you should use :
int main(void)
In this while q is never updated so i guess infinite loop?
while (q <= end)
{
tempArr[k] = &arr[q];
k++;
p++;
}
Can you provide me your inputs and output you want?
I have tried your code and i'm not getting your error.

Implement a function that returns the longest sequence of either 1s or 0s and the first index of it

I need write a function that return the longest sequence of either 1s or 0s for a given array (of 1s and 0s). It also needs to return in a pointer the index at which this longest sequence begins.
Say for example I have the array
a[]={1, 0, 0, 0, 1, 0, 0, 1}
The function returns
3, 1
where 3 is the longest sequence (in this case of 0s) and 1 is the index at which it begins.
What I did was this:
int longestSequence(int a[], int n, int* begin)
{
int count=1;
int max_length=1;
int i;
for(i=1;i<n;i++)
{
if(a[i]==a[i-1])
{
count+=1;
}
else if (count>max_length)
{
max_length=count;
count=1;
}
else
{
count=1;
}
}
if(count>max_length)
{
max_length=count;
}
return max_length;
}
I tried a couple of examples to see if the function returns the longest sequence and it works. However, I'm unable to find a way to return the right index at which it begins.
Any help would be much appreciated.
try this:
int longestSequence(int a[], int n, int *begin){
int i, count, max_length = 1;
*begin = 0;
for(i = 0; i + max_length < n; i += count){
for(count = 1; i + count < n && a[i] == a[i + count]; ++count)
;
if(count > max_length){
max_length = count;
*begin = i;
}
}
return max_length;
}
your code nearly works.
add max_index = i - count; just below max_length=count; (both places)
also define int max_index; near the top.
Try this small edit:
int longestSequence(int a[], int n, int* begin)
{
int count=1;
int max_length=1;
int out_index = 0;
int i;
for(i=1;i<n;i++)
{
if(a[i]==a[i-1])
{
count+=1;
}
else if (count>max_length)
{
max_length=count;
out_index = i - count;
count=1;
}
else
{
count=1;
}
}
if(count>max_length)
{
max_length=count;
out_index = i - count;
}
*begin = out_index;
return max_length;
}

Unexpected out - Finding Maximum and Second Maximum

I am trying to implement a simple tournament in C.
#include <stdio.h>
int main(void) {
int tourn[100], n, i;
printf("Give n:");
scanf("%d", &n);
printf("\n n = %d \n", n);
for(i = n; i <= (2*n)-1; i++)
scanf("%d", &tourn[i]);
build(tourn, n);
printf("\n Max = %d \n",tourn[1]);
printf("\n Next Max = %d \n",nextmax(tourn, n));
}
void build(int tourn[], int n) {
int i;
for(i = 2*n-2; i > 1; i = i-2)
tourn[i/2] = max(tourn[i], tourn[i+1]);
}
int nextmax(int tourn[],int n) {
int i = 2;
int next;
next = min(tourn[2], tourn[3]);
while(i <= 2*n-1) {
if(tourn[i] > tourn[i+1]) {
next = max(tourn[i+1], next);
i = 2*i;
}
else {
next = max(tourn[i], next);
i = 2*(i+1);
}
}
return(next);
}
int max(int i,int j) {
if(i > j)
return i;
else
return j;
}
int min(int i,int j) {
if(i < j)
return i;
else
return j;
}
The output for n = 5 and
1 2 3 4 5
is
Max = 4195048
Next Max = 32588
and this output varies each time by a small amount!
if I place a test printf command before the build function, it doesn't execute.
Can someone find the error/explain the output?
Thanks :)
Your code seems pretty broken to me. you don't mind to address beyond your array boundaries, which is a good way of producing random results:
while(i <= 2*n-1){
if(tourn[i]>tourn[i+1]){
next = max(tourn[i+1],next);
i=2*i;
} else {
next = max(tourn[i],next);
i=2*(i+1);
}
}
Your (logical) array is of size 2n. if i reaches the "highest" value, you test tourn[i + 1], which is tourn[2n].

Resources