The following code gives me a terminated by signal SIGSEGV (Address boundary error)
:
void rec(int x, int *arr, int *size) {
if (x < 0) {
rec(-x, arr, size);
return;
}
arr = realloc(arr, sizeof(int) * ++(*size));
*(arr + (*size) - 1) = x % 10;
if (x % 10 != x)
rec(x / 10, arr, size);
}
int main() {
int *arr = malloc(sizeof(int));
int *size = malloc(sizeof(int));
*size = 0;
rec(20, arr, 0);
}
I already figured our that the arr
counter in the main method won't hold the desired result, but I still can't understand why I'm getting an error.
For starters these memory allocations
int *arr = malloc(sizeof(int));
int *size = malloc(sizeof(int));
does not make a sense. They are redundant.
You could just write
int *arr = NULL;
size_t size = 0;
Secondly the variable size is declared but not used because instead of the variable you passed the integer constant 0
rec(20, arr, 0);
So within the function rec
void rec(int x, int *arr, int *size);
the pointer size
was initializer by the null pointer constant 0. That is size
is a null pointer within the function and using a null pointer to access memory results in undefined behavior.
Also you should pass the pointer to the function by reference. Otherwise passing it to the function does not make a great sense because the pointer in main will not be changed.
The code in main could look like
int *arr = NULL;
size_t size = 0;
rec( 20, &arr, &size );
Pay attention to that you should free all the allocated memory when it will not be used any more.
Correspondingly the function should be declared like
void rec(int x, int **arr, size_t *size);
Use the type size_t
instead of the type int
because this unsigned integer type is the type of the second argument of the function realloc
.
In general to get the result of realloc you should use an intermediate variable because the function can return a null pointer and the current pointer will be lost.
Also pay attention to that the call of the function is unsafe and can result in an infinite recursion due to this if statement
if (x < 0) {
rec(-x, arr, size);
return;
}
when the user passes to the function the value of x equal to INT_MIN
.
Consider the following demonstrative program.
#include <stdio.h>
#include <limits.h>
int main(void)
{
int x = INT_MIN;
printf( "x = %d\n", x );
printf( "-x = %d\n", -x );
return 0;
}
Its output might look like
x = -2147483648
-x = -2147483648
As you can see negating the value of the variable x you get the same negative value. So maybe it is better to declare the first function parameter as having the type unsigned int
.
Your function can look for example the following way as it is shown in the demonstrative program below.
#include <stdio.h>
#include <stdlib.h>
int rec( unsigned int x, unsigned int **arr, size_t *size )
{
const unsigned int Base = 10;
unsigned int *tmp = realloc( *arr, sizeof( int ) * ++*size );
int success = tmp != NULL;
if ( success )
{
*arr = tmp;
*( *arr + *size - 1 ) = x % Base;
if ( x % Base != x )
{
success = rec( x / Base, arr, size );
}
}
return success;
}
int main(void)
{
unsigned int *arr = NULL;
size_t size = 0;
rec( 123456789, &arr, &size );
for ( size_t i = 0; i < size; i++ )
{
printf( "%u", *( arr + i ) );
}
putchar( '\n');
free( arr );
return 0;
}
The program output is
987654321