Segmentation fault when copying a portion of an array in c

450 views Asked by At

I have a function here that copies a portion of an array (first to last) to a new array. When I ran the code, I ended up getting seg fault. I know that seg faults happen when I don't allocate enough space to the array or when I try to access memory that hasn't been allocated. But for my len, I already set it as last-first+1 which should be enough to encompass the portion of the array that I want to copy. But why does it still give me seg fault? Or am I missing something?

Here is the struct for my code I've done:

typedef struct {
  int* data;
  unsigned int len;
} intarr_t;

Here's the function to copy the portion of the array to a new one:

intarr_t* intarr_copy_subarray( intarr_t* ia, 
                unsigned int first, 
                unsigned int last )
{
    unsigned int len = last-first+1;
    intarr_t* newia = malloc(sizeof(intarr_t));
    assert (newia);
    newia->data = malloc(sizeof(int)*len);
    assert (newia->data);
    newia->len = len;
    if (newia == 0 || ia == NULL || last < first)
    { 
        return NULL;
    }
    else
    {
        for (int x = first; x <= last; x++)
        {
            memcpy (newia->data[x], ia->data[x], (len*sizeof(int)));
        }
        return newia;
    }
    free (newia);
    return 0;
}
2

There are 2 answers

2
Vlad from Moscow On BEST ANSWER

Change these statements

    for (int x = first; x <= last; x++)
    {
        memcpy (newia->data[x], ia->data[x], (len*sizeof(int)));
    }

to

memcpy ( newia->data, ia->data + first, len * sizeof( int ) );

or to

    for ( unsigned int i = 0; i < len; i++ )
    {
        newia->data[i] = ia->data[i + first];
    }

Also this condition

if (newia == 0 || ia == NULL || last < first)
{ 
    return NULL;
}

is erroneous. You have to free allocated memory in this block in case either ia is equal to NULL or last < first.

You should check these conditions before allocating memory.

0
Kranthi Kumar On

It is the problem with the memcpy statement which you have in the for loop. Kindly note that when you are giving newia->data[x] it is getting converting to the integer value at that particular pointer.

So for example data is pointing to an integer variable with value like newia->data[x] = 2 and second one as to another integer variable ia->data[x] = 3 then your memcpy becomes

memcpy(2, 3, len*sizeof(int) );

So effectively you are ending up copying data from address 3 to address 2 for which both are not allocated by you.

You need to follow the way suggested by Vlad from Moscow.