Reputation: 103
I am currently attempting to create a source code that meets these following requirements:
Requirements:
// Get a deep copy of a portion of array from index first to index last
// inclusive. If successful, return a pointer to a newly-allocated intarr_t containing a copy of the specfied section.
// If an error occurs, i.e. array is null, first or last are out of bounds, last < first, or memory allocation fails, return a null pointer.
I have completed the first two requirements, but it seems that my logic for the third one is faulty, and no matter how much I test it, I can't seem to find the corner case that occurs.
My code:
intarr_t* intarr_copy_subarray( intarr_t* array,
unsigned int first,
unsigned int last )
{
intarr_t *tmp;
tmp = malloc((last-first)*sizeof(intarr_t));
// it seems that my if statement is not meeting the requirement in bold.
if(first>=0 && last<= array->len && array != NULL && first > last && tmp != NULL)
{
//perform copying here
return tmp; // pointer to new array containing the copied stuff
}
else
{
return NULL;
}
}
typedef struct {
int* data;
unsigned int len;
} intarr_t;
There seems to be a case where it returns NULL when it is not supposed to and it has to do with my if statement. Note that I am passing my function a typedef structure that contains a pointer to an array and the length, but that isn't the problem. Should I be using OR statements rather than AND statements?
Upvotes: 2
Views: 258
Reputation: 310910
The function can look like
intarr_t* intarr_copy_subarray( const intarr_t *array,
unsigned int first,
unsigned int last )
{
if ( array == NULL || array->data == NULL || last < first || array->len <= last )
{
return NULL;
}
intarr_t *tmp = malloc( sizeof( intarr_t ) );
if ( tmp )
{
tmp->data = malloc( ( last - first + 1 ) * sizeof( int ) );
if ( tmp->data == NULL )
{
free( tmp );
tmp = NULL;
}
else
{
tmp->len = last - first + 1;
for ( unsigned int i = 0; i < tmp->len; i++ )
{
tmp->data[i] = array->data[first + i];
}
}
}
return tmp;
}
Upvotes: 0
Reputation: 25752
First of all check for NULL first:
if( !array )
return NULL ;
Then don't allocate just yet, but check if you arguments are in bounds:
if( first>=0 && last< array->len && first <= last )
{
Then allocate memory and if successful copy the array to the new subarray.
Your example allocation isn't correct given that intarr_t
( _t is a reserved identifier by the way ), holds a pointer to the int array. You should allocate one intarr_t
and then the array it points to:
intarr_t tmp = malloc(sizeof(intarr_t)) ;
if( tmp )
{
tmp->data = malloc( sizeof( int ) * ( last - first + 1 ) ) ;
//check if malloc succeeded again
tmp->len = last - first + 1 ;
...
Upvotes: 1