【问题标题】:Segmentation fault when trying to resize a 2D Array尝试调整二维数组大小时出现分段错误
【发布时间】:2017-04-18 09:53:49
【问题描述】:

这是代码:

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");
}

nc=2,nl=3

所以,当我调用 main resize(p,&amp;nl,&amp;nc,4,2) 时,如果 resize 函数首先裁剪矩阵的底部,则会进入第二个函数,因为新高度小于旧高度(nh > nl),裁剪后,它会在剩余的行 (2) 上运行,并在 reallocs 内存中进行,以便它可以用 {255,255,255} 填充新宽度,一切顺利。

但是,当我调用resize(p,&amp;nl,&amp;nc,2,4) 时,如果调试器没有显示错误并且正在填充二维数组,它会继续执行第一个操作,但是当它在 main 中到达 printf 时,我会遇到分段错误。可能是什么问题?

【问题讨论】:

  • void crop --> int **crop and return v; or int **v --> int ***v, v=realloc(v, --> *v=realloc(*v,, v[i]=realloc(v[i], --> @987654341 @等等。
  • 您应该查看proper C formatting。或了解如何thoroughly obfuscate your code
  • 严格来说,这不是二维数组,而是指向一维数组的指针数组。更多关于此question 的信息来自 C 标签常见问题解答。

标签: c arrays matrix realloc calloc


【解决方案1】:

正如 BLUEPIXY 用 void crop --> int **cropreturn v; 暗示的那样,我们必须考虑到 realloc 可能会移动指向的区域,因此调用的函数realloc 因为你的行指针数组必须返回可能改变的内存指针,调用函数是用返回的值重新分配它。这不仅适用于函数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);
    …
}

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 1970-01-01
    • 2021-03-25
    • 2022-01-21
    • 2015-04-13
    • 1970-01-01
    • 1970-01-01
    • 2020-06-14
    • 2018-09-22
    相关资源
    最近更新 更多