[英]Segmentation fault when trying to resize a 2D Array
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
令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 realloc
s memory so that it can fill the new width with {255,255,255}
and it all goes well. 因此,当我调用main resize(p,&nl,&nc,4,2)
,如果它首先裁剪矩阵的底部,导致新高度小于旧高度( nh
> nl
),在裁剪后继续在其余的行(2)上,并重新realloc
内存,以便可以用{255,255,255}
填充新宽度,并且一切顺利。
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. 但是,当我调用resize(p,&nl,&nc,2,4)
,它会在第一个条件上继续运行,如果调试器未显示任何错误,并且它正在填充2D数组,但是当它进入printf
中的printf
时,我得到了分段故障。 What could be the problem? 可能是什么问题呢?
As BLUEPIXY hinted at with void crop
--> int **crop
and return v;
正如BLUEPIXY所提示的那样,使用void crop
-> int **crop
并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. ,我们必须考虑到realloc
可能会移动指向的区域,因此,为您的行指针数组调用realloc
的函数必须返回可能已更改的内存指针,并且调用函数将使用返回的值对其进行重新分配。 This applies not only to the function crop()
, but also to resize()
, so the necessary changes are: 这不仅适用于函数crop()
,还适用于resize()
,因此必要的更改是:
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);
…
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.