I'm trying to write a code that can check whether a dynamic array is sorted, but I get an error. The code has to be recursive.
When I input an unsorted array there seems to be no problem, but when I input a sorted array the program halts abruptly with:
Process return -1073741571
Here is my code:
#include <stdio.h>
#include <stdlib.h>
int ordenado(int*);
int main() {
int i = 0, res = 0;
int*arr = NULL;
arr = (int*) malloc(sizeof (int));
while (arr[i] != 0) {
i++;
arr = (int*) realloc(arr, (i + 1) * sizeof (int));
scanf("%d", &arr[i]);
}
res = ordenado(arr);
printf("\n%d ", res);
return 0;
}
int ordenado(int* arr) {
if (arr[0] == 0) {
return 1;
}
if (arr[0] <= arr[1]) {
return ordenado(arr++);
}
else return 0;
}
Sorry my first answer was not right. I corrected below.
scanf("%d", &arr[i]); before the loop to fill arr[0]ordenado function
0 then return 1x but the next element is 0 then return 1 (Note the || is a short circuit. If you don't hit 0 then there is a next element. So you can check it for 0 here too.)return 0 (I think that's faster)not 0 and call ordenado(++arr) (prefix, not postfix)Note about prefix and postfix:
The difference between prefix and postfix in many programming languages it the execution order. Assume i and j being 0 before execution in both statements.
i += ++j;
The above code is equivalent to this
j = j + 1;
i = i + j;
While the below code
i += j++;
is equivalent to this
i = i + j;
j = j + 1;
I.e. in prefix the increment takes place before the expression is evaluated, while in postfix the increment takes place after the expression is evaluated. This usually holds true not matter the data type (i.e. includes pointer).
Your line of code
return ordenado(arr++);
is equivalent with
return ordenado(arr);
a++;
which leads to infinite number of function calls as @BLUEPIXY pointed out.
#include <stdio.h>
#include <stdlib.h>
int ordenado(int*);
int main() {
int i = 0, res = 0;
int* arr = NULL;
arr = (int*) malloc(sizeof (int));
scanf("%d", &arr[i]);
while (arr[i] != 0) {
i++;
arr = (int*) realloc(arr, (i + 1) * sizeof (int));
scanf("%d", &arr[i]);
}
res = ordenado(arr);
printf("\n%d ", res);
return 0;
}
int ordenado(int* arr) {
if (arr[0] == 0 || arr[1] == 0)
return 1;
if (arr[0] > arr[1])
return 0;
else
return ordenado(++arr);
}
Input: 0
Output: 1
Input: 1 newline 0
Output: 1
Input: 1 newline 2 newline 3 newline 0
Output: 1
Input: 2 newline 1 newline 0
Output: 0
Input: 1 newline 2 newline 3 newline 2 newline 3 newline 0
Output: 0
In these lines:
arr = malloc(sizeof (int));
while (arr[i] != 0)
You cannot count on malloc'd memory having any particular value. It is uninitialized.
It looks like you are using an input zero as a sentinel. The proper way to do this is:
int i = 0;
int *arr = malloc(sizeof (int));
do {
i++;
arr = realloc (arr, (i + 1) * sizeof (int));
scanf ("%d", &arr[i-1]);
} while (arr[i-1] != 0);
I have also fixed element zero not having been assigned a value.
I suspect the error you experienced was caused by runaway recursion.
Your code has multiple problems:
0)0;arr before incrementing it, hence causing an infinite recursion. The fact that you get an error proves that the compiler does not handle tail recursion, and your code eventually fails with a stack overflow.If you can change the API for the ordenado function, you should pass it the number of actual elements in the array. This function is supposed to be recursive, choose an algorithm that will limit the recursion to avoid stack overflow if the compiler does not detect tail recursion.
Here is my suggestion:
#include <stdio.h>
#include <stdlib.h>
int ordenado(int *array, int count);
int main() {
int i = 0, n, res;
int *arr = NULL;
while (scanf("%d", &n) == 1 && n != 0) {
arr = realloc(arr, (i + 1) * sizeof(int));
if (!arr) {
printf("out of memory\n");
return 1;
}
arr[i++] = n;
}
res = ordenado(arr, i);
printf("%d\n", res);
return 0;
}
int ordenado(int *arr, int n) {
int m = n >> 1;
return (m == 0) ||
(ordenado(arr, m) && arr[m - 1] <= arr[m] && ordenado(arr + m, n - m));
}
NB: Reallocating the array one int at a time is painfully inefficient, but is not the topic of this discussion.