0

This is the code:

int **mat(int nl, int nc) {
  int i;
  int **v = malloc(nl * sizeof(int *));

  for (i = 0; i < nl; i++) {
    v[i] = calloc(nc, sizeof(int));
  }
  return v;
}


void crop(int **v,int *nl,int *nc,int l1,int c1,int l2,int c2)

{

int i,j;

for(i=0;i<(l2-l1);i++)
    for(j=0;j<(c2-c1)*3;j++)
        v[i][j]=v[l1+i][c1*3+j];

for(i=l2-l1;i<*nl;i++)
    free(v[i]);

v=realloc(v,(l2-l1)*sizeof(int *));

for(i=0;i<*nl;i++)
    v[i]=realloc(v[i],(c2-c1)*3*sizeof(int));

int x=l2-l1,y=c2-c1;
*nl=x;
*nc=y;

}


void resize(int **v,int *nl,int *nc,int nw,int nh)
{
int i,j,h=*nl,w=*nc,x=nh,y=nw;

if(nh>h && nw<=w)
    {
        crop(v,&w,&h,0,0,*nl,nw);
        v=realloc(v,nh*sizeof(int *));
        for(i=*nl;i<nh;i++)
        {
        v[i]=calloc(nw*3,sizeof(int));
        for(j=0;j<=nw*3;j++)
        v[i][j]=255;
        }

    }
    if(nh<=h && nw>w)
    {
        crop(v,&w,&h,0,0,nh,*nc);
        for(i=0;i<nh;i++)
        {
        v[i]=realloc(v[i],nw*3*sizeof(int));
        for(j=*(nc)*3;j<=nw*3;j++)
        v[i][j]=255;
        }
    }
    *nl=x;
    *nc=y;
}

int main(){

int nl,nc,i,j;
scanf("%d%d",&nc,&nl);
int **p = mat(nl,nc*3);

for(i=0;i<nl;i++)
    for(j=0;j<nc*3;j++)
        p[i][j]=i+j;

resize(p,&nl,&nc,2,4);

for(i=0;i<nl;i++)
{
    for(j=0;j<nc*3;j++)
    printf("%d ",p[i][j]);
    printf("\n");
}

Let nc=2,nl=3

So, when I call in main resize(p,&nl,&nc,4,2), the resize function goes in the second if it first crops the bottom of the matrix cause the new height is smaller that the old height (nh > nl), after the crop it goes on the remaining lines (2) and it reallocs memory so that it can fill the new width with {255,255,255} and it all goes well.

However, when I call resize(p,&nl,&nc,2,4), it goes on the first if, the debugger show no errors and it is filling up the 2D Array, but when it gets to printf in main, I get segmentation fault. What could be the problem?

Kirill Kobelev
  • 10,252
  • 6
  • 30
  • 51
Andrei
  • 31
  • 1
  • 8
  • `void crop` --> `int **crop` and `return v;` or `int **v` --> `int ***v`, `v=realloc(v,` --> `*v=realloc(*v,`, `v[i]=realloc(v[i],` --> `(*v)[i]=realloc((*v)[i],`and so on. – BLUEPIXY Dec 03 '16 at 16:37
  • You should look into [proper C formatting](//prohackr112.tk/r/proper-c-formatting). Or learn how to [thoroughly obfuscate your code](//prohackr112.tk/r/proper-c-obfuscation). – MD XF Dec 03 '16 at 17:07
  • Strictly speaking, this is **not** a 2D array but an array of pointers to 1D arrays. More on this [question](https://stackoverflow.com/q/42094465/3545273) from C tag FAQ. – Serge Ballesta Mar 19 '18 at 09:00

1 Answers1

0

As BLUEPIXY hinted at with void crop --> int **crop and return v;, we must take into account that realloc may move the area pointed to, thus a function which calls realloc for your row pointer array has to return the possibly changed memory pointer, and the calling function is to reassign it with the returned value. This applies not only to the function crop(), but also to resize(), so the necessary changes are:

int **crop(int **v, int *nl, int *nc, int l1, int c1, int l2, int c2)
{
    …
    return v;
}

int **resize(int **v, int *nl, int *nc, int nw, int nh)
{
    …
        v = crop(v, &w, &h, 0, 0, *nl, nw);
    …
        v = crop(v, &w, &h, 0, 0, nh, *nc);
    …
    return v;
}

int main()
{
    …
    p = resize(p, &nl, &nc, 2, 4);
    …
}
Armali
  • 18,255
  • 14
  • 57
  • 171