C: Как передать двойной указатель на функцию - PullRequest
13 голосов
/ 02 декабря 2010

Я получаю ошибку сегментации, когда передаю двойные указатели функции для инициализации памяти

int main()
{
    double **A;
    initialize(A, 10, 10);
 ......
}

void initialize(double **A, int r, int c)
{
   A = (double **)malloc(sizeof(double *)*r);
   for(int i = 0; i< r; i++) {
        A[i] = (double *)malloc(sizeof(double) *c);
        for(int j = 0; j < c; j++) {
            A[i][j] = 0.0;
        }
   }
}

Как я могу передать двойные указатели на функции .....

Ответы [ 5 ]

17 голосов
/ 02 декабря 2010

Как уже говорили другие, вам нужно взять указатель на указатель на указатель в вашей функции инициализации.Вот как меняется функция initialize:

void initialize(double ***A, int r, int c)
{
   *A = (double **)malloc(sizeof(double *)*r);
   for(int i = 0; i< r; i++) {
        (*A)[i] = (double *)malloc(sizeof(double) *c);
        for(int j = 0; j < c; j++) {
            (*A)[i][j] = 0.0;
        }
   }
}

И main будет:

int main()
{
    double **A;
    initialize(&A, 10, 10);
}

Кроме того, код, который вы опубликовали, не должен вызывать ошибки сегментации при передачеуказатель A. Ошибка сегментации наиболее вероятна, когда вы вернетесь из функции и попытаетесь получить доступ к A, поскольку A в main не будет инициализирован.Только его копия инициализируется так, как вы это делаете, и эта копия является локальной для функции initialize, поэтому она теряется при возврате.

17 голосов
/ 02 декабря 2010

Если вы хотите изменить указатель на указатель, необходимо передать указатель на указатель на указатель.

1 голос
/ 02 декабря 2010

Это то, что вы не хотите делать.Вместо ненужного использования аргумента out для этого, выделите в функции и верните результат.Сделайте это вместо:

int main() 
{
    double **A;
    A = initialize(A10, 10);
}

double** initialize(int r, int c)
{
   double **A;
   A = malloc(sizeof(double *)*r);
   for(int i = 0; i< r; i++) {
        A[i] = (double *)malloc(sizeof(double) *c);
        for(int j = 0; j < c; j++) {
            A[i][j] = 0.0;
        }
   }
  return A;
}
1 голос
/ 02 декабря 2010
  1. Вы не проверяете наличие ошибок нехватки памяти. Сбой.

  2. Вы передаете BY VALUE неинициализированное значение A для initialize (), а затем инициализируете его. Но вернемся к main (), эта локальная переменная A все еще неинициализирована. Вместо этого вам может потребоваться, чтобы initialize () вернул double** (например, A = initialize(...)) или изменил initialize (), чтобы его первый формальный параметр был double ***pA, который вы инициализируете с помощью *pA = (double**)malloc(...);

1 голос
/ 02 декабря 2010

Во-первых, A внутри инициализации является копией A в main - поэтому, когда вы вернетесь к main, A все еще неинициализирован. Если вы попробуете это использовать - бум!

Чтобы передать его в initialize «по ссылке», вам нужно изменить тип параметра на double*** и передать &A в main. Затем, когда вы используете его в initialize, вам нужно разыменовывать его каждый раз, то есть *A.

...