ошибка сегментации двойной указатель realloc - PullRequest
0 голосов
/ 27 декабря 2018

У меня есть небольшая часть простого кода, который продолжает вызывать ошибку сегментации каждый раз, когда я выполняю цикл realloc for во втором операторе if.

  *x = (int**)realloc(*x,nNew*sizeof(int*));

   for(int i=0;i<n;i++) 
      x[i] = (int*) realloc(x[i],nNew*sizeof(int));  // seg fault

Я думаю, что выделение памяти имеетбыло сделано правильно (очевидно, нет), но я не могу найти ошибку. В первом операторе if (где я освобождаю память) он работает правильно.

Извините за плохой формат.

void update(int **x,int n,int nNew)
{
   int  temp;    

   if(n>nNew)
   {
     *x = (int **) realloc(*x,nNew*sizeof(int*));

     for(int i=0;i<n;i++)
       *(x+i) =(int *) realloc(x[i],nNew*sizeof(int));

     printf("temp %d",x[nNew-1][nNew-1]);
   }

   else if(n<nNew)
   {
      temp = x[n-1][n-1];

     *x = (int**)realloc(*x,nNew*sizeof(int*));

     for(int i=0;i<n;i++) 
       x[i] = (int*) realloc(x[i],nNew*sizeof(int));   // seg fault

     printf("temp %d",**temp);
     for(int i=n;i<(nNew);i++)
     {
        for(int j=n;j<(nNew);j++)
          x[i][j] = temp;
     }
   }
} 

int main()
{
  int nNew = 9;
  int n = 8;

  int **x = (int **) malloc(n*sizeof(int*));

  for (int i=0; i<n; i++) 
    x[i] = (int *)malloc(n * sizeof(int)); 


  int count=0 ;
  for(int i=0;i<n;i++)
  {
     count ++;
     for(int j=0;j<n;j++)
       x[i][j] = count;
  } 

  update(x,n,nNew);

  for(int i=0;i<nNew;i++)
    free(x[i]);
  free(x);

  return 0; 
}

1 Ответ

0 голосов
/ 27 декабря 2018

Вы не перераспределяете то, что вы думаете.

Когда вы делаете это:

*x = (int**)realloc(*x,nNew*sizeof(int*));

для (int i = 0; i

, поскольку x имееттип int **, *x имеет тип int *. Кроме того, *x совпадает с x[0]. Таким образом, вы не перераспределяете массив указателей в первой строке, а первый массив int.Вам нужно вызвать realloc для исходного указателя, и , вам нужно передать адрес этого указателя, чтобы изменение было видно в вызывающей программе.

Затем для перераспределенияДля отдельных массивов вам нужно вызвать realloc на исходном n, чтобы увеличить или уменьшить их, затем либо free дополнительные строки, если они растут, либо malloc новые добавленные строки. В случае роста вы хотите realloc массив указателей fisrt, и в случае сокращения вы хотите сделать это последним.

Так что после этих изменений ваша функция update должна выглядеть так:

void update(int ***x, int n, int nNew)
{
    if(n>nNew) {
        // shrink each row to be kept
        for(int i=0;i<nNew;i++)
           (*x)[i] = realloc((*x)[i],nNew*sizeof(int));

        // free the extra rows
        for(int i=nNew;i<n;i++)
            free((*x)[i]);

        // shrink the list of rows
        *x = realloc(*x,nNew*sizeof(int*));

    } else if(n<nNew) {
        // grow the list of rows
        *x = realloc(*x,nNew*sizeof(int*));

        // grow the existing rows
        for(int i=0;i<n;i++)
            (*x)[i] = realloc((*x)[i],nNew*sizeof(int));

        // create the new rows
        for(int i=n;i<nNew;i++)
            (*x)[i] = malloc(nNew*sizeof(int));
    }
}

ИВы называете это так:

update(&x,n,nNew);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...