Andrew
Andrew

Reputation: 149

Resizing an array (c)

I'm trying to resize an array to contain values with length of "newlen". If newlen is less than the original array length, the end of the array is discarded. If newlen is greater, the new integers should be zero. I came up with this function, but when I test it, I get segmentation fault. I also don't know how to add the zeroes to the end, how can I keep track of the index so that I can add int zeroes at the end? I did the first case (where newlen is less than len), but don't know how to do the other case.

Here's the structure for the array:

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

My function:

array_size( intarr_t* p, unsigned int newlength )

{

  int i,m = 0;

  if (newlength < len) 
        int *tmp;
    tmp = realloc(p->data, (p->newlen)* sizeof *p->data);
    if(tmp)

  {
    for (i; newlength < p->len; i++)
        {  for (m; newlength < p->len; m++)

    {
        p->data[i] = p->data[m];
    }
        }

  }

}

Upvotes: 0

Views: 554

Answers (2)

avinash pandey
avinash pandey

Reputation: 1381

As you are not initializing i anywhere before using it in the loop may be it's because of this.

Also for the code

for (m; newlength < p->len; m++)

where are you re initializing this value for second and other passes of the for loop.Also both the loops are infinite loops.

To implement the second case you can do something like this

if(newlength > p->len)
{
    int old_length = p->len;
    p = realloc(p->data, newlength * sizeof(p->data));
    if(p)
        memset(p + old_length,0,(newlength - old_length) * sizeof(p->data));
}

Your entire working function will be like this

array_size( intarr_t* p, unsigned int newlength ) {
    intarr_t * tmp;
    if(newlength < p->len) {
        tmp = realloc(p->data, newlength * sizeof(p->data)); //realloc will automatically discard elements after new length
        if(tmp) {
            p = tmp;
            p->len = newlength;
        }
    }
    else if(newlength > p->len)
    {
        int old_length = p->len;
        tmp = realloc(p->data, newlength * sizeof(p->data));
        if(tmp){
            p = tmp;
            p->len = newlength;
            memset(p + old_length,0,(newlength - old_length) * sizeof(p->data));//for setting trailing element to 0
        }   
    }
}

Upvotes: 1

Peter
Peter

Reputation: 36597

The pointer supplied to realloc() (p->data) is not changed.

Usage of realloc() normally needs to be something like this

tmp = realloc(old_pointer, new_number * sizeof(*tmp));
if (tmp == NULL)
{
      /*   an error occur and old_pointer remains unchanged */
      /*   need to recover */
}
else
{
     old_pointer = tmp;
     length = new_number;
}

I'm assuming tmp and old_pointer are the same type in the above.

Then you can initalise the additional elements of old_pointer (assuming the array size is being increased).

Upvotes: 1

Related Questions