Reputation: 16142
int *rrange(int start, int end);
I was asked, to write a function and allocate with malloc an array of integers, fill it with consecutive
values that begin at end and end at start (Including start and end !), then
return a pointer to the first value of the array. The functions works with small numbers, when tested with big numbers I get seg fault
. And I think I got seg fault
due to reaching the limit of int
. How can I solve this issue?.
/*- With (1, 3) you will return an array containing 3, 2 and 1
- With (-1, 2) you will return an array containing 2, 1, 0 and -1.
- With (0, 0) you will return an array containing 0.
- With (0, -3) you will return an array containing -3, -2, -1 and 0.*/
#include <stdlib.h>
int *rrange(int start, int end)
{
int *range;
int i;
i = 0;
range = (int *)malloc(sizeof(int *));
if (end <= start)
{
while (end <= start)
range[i++] = end++;
}
else
{
while (end >= start)
range[i++] = end--;
}
return (range);
}
= Test 1 ===================================================
$> ./pw53y11cbachacu14eue5cab
$> diff -U 3 user_output_test1 test1.output | cat -e
Diff OK :D
= Test 2 ===================================================
$> ./o1jrm4t3vqengizvj1tlwab4 "21" "2313" "12"
$> diff -U 3 user_output_test2 test2.output | cat -e
Diff OK :D
= Test 3 ===================================================
$> ./usl3i1tc1xv9tr1gs9n5x5vr "2147483647" "2147483640" "7"
$> diff -U 3 user_output_test3 test3.output | cat -e
--- user_output_test3 2016-06-08 16:26:16.000000000 +0200$
+++ test3.output 2016-06-08 16:26:16.000000000 +0200$
@@ -1,8 +1,8 @@$
-0$
-0$
-0$
-0$
-0$
-0$
-0$
+2147483640$
+2147483641$
+2147483642$
+2147483643$
+2147483644$
+2147483645$
+2147483646$
$
Diff KO :(
Grade: 0
= Final grade: 0 ===============================================================
Upvotes: 2
Views: 148
Reputation: 16540
the following code:
start
is greater than end
however, that was not part of the criteriaand now the code:
/*- With (1, 3) you will return an array containing 3, 2 and 1
- With (-1, 2) you will return an array containing 2, 1, 0 and -1.
- With (0, 0) you will return an array containing 0.
- With (0, -3) you will return an array containing -3, -2, -1 and 0.*/
#include <stdlib.h> // exit(), EXIT_FAILURE
#include <stdio.h> // perror()
#include <math.h> // abs()
int *rrange(int start, int end)
{
int *range = NULL;
if( NULL == (range = malloc( sizeof(int) *((size_t)abs(end - start) +1) ) ) )
{ // then malloc failed
perror( "malloc failed" );
exit( EXIT_FAILURE );
}
for( int index = 0; index < abs(end-start)+1; index++ )
{
range[ index ] = start+index;
}
return (range);
} // end function: rrange
Upvotes: 0
Reputation: 1
The argument to malloc
should be number_of_integers * sizeof(int)
. The value of number_of_integers
can for example be calculated as abs(start-end)+1
, but I'd instead do the malloc
inside the if
-statement where the relation between start and end is known.
Upvotes: 0
Reputation: 5457
segfault occurs due to wrong memory allocation
range = (int *)malloc(sizeof(int *));
this would allocate a memory of the size of an integer pointer. but to allocate memory for numbers you need to create required amount of memory for each number this way :
range = malloc(no_of_elements*sizeof(int));
NOTE: use
n
as global variable so that you can know the size of array even in function() where you print
and I've modified your function
int *rrange(int start, int end)
{
int *range;
int i;
if(start>end)
return rrange(end,start); //so that start is always <end
n=end-start+1; // n globally declared
range=malloc(n*sizeof(int)); //casting is not required
if(range==NULL)
{// check if memory was successfully allocated if not exit
printf("fail");
exit(1);
}
for(i=0;i<n;i++,start++)
{
range[i]=start;
}
return range;
}
you can now write your main as:
int main()
{
int x,y,*r,i;
scanf("%d%d",&x,&y);
r=rrange(x,y);
for(i=0;i<n;i++)
{
printf("%d,",r[i]);
}
return 0;
}
Upvotes: 1
Reputation: 739
I'm surprised this worked with any range larger than 2. You're allocating 8B of storage (assuming you're running a 64b machine), or whatever is pointer size in general.
What you want instead is a malloc expression that depends on the difference between start
and end
(giving you the array size) and sizeof(int)
(giving you the array element size).
Unrelated note: make sure to free the storage when you stop using the array, otherwise your program will leak like a sieve.
Upvotes: 0
Reputation: 9639
Your problem comes from the malloc
:
Instead of
range = (int *)malloc(sizeof(int *));
You should write:
range = malloc(nb_of_integer_in_range * sizeof (int));
Up to you to compute nb_of_integer_in_range
, something like:
int nb_of_integer_in_range;
if (end > start)
{
nb_of_integer_in_range = end - start + 1;
}
else ...
Upvotes: 4