2013-12-06 3 views
1

У меня есть структура, которая использует двойные указатели, чтобы сделать матрицу:двойного указателя и выделение памяти

typedef struct 
{ 
     int rows, cols; 
     int** element; 
}Matrix; 

Я пишу функцию, которая инициализирует матрицу путем динамического выделения памяти для этих структур. Это код, который я написал, но я получаю ошибку сегментации, когда пытаюсь получить доступ к a-> rows, cols или element в другой функции или в основном.

void matrixInit (Matrix* ma, int m, int n) 
{ int i; 
    ma=(Matrix*)malloc(sizeof(Matrix)); 
    ma->rows=m; 
    ma->cols=n; 

    ma->element=malloc(m*sizeof(int*)); 
    for(i=0;i<m;i++) 
     {ma->element[i]=malloc(n*sizeof(int)); 
     } 

} 

Любая помощь пожалуйста?

+1

Где декларация 'ma'? Почему у вас есть два аргумента с именем 'm'? – kviiri

+0

есть. Прости. он был первоначально назван matx, и я изменил его на m, чтобы упростить его. – user3075598

+0

Вы должны показать пример доступа, который вызывает ошибку сегментации. –

ответ

0

При вызове функции, как это, вы передаете ему значение указателя на матрице. Когда вы фактически создаете матрицу в функции, вы назначаете ее только локально.

Вы должны передать указатель на переменную, в которой должен храниться указатель на матрицу, то есть Matrix **ma.

void matrixInit (Matrix **ma_ptr, int m, int n) 
{ 
    int i; 
    *ma_ptr = (Matrix*)malloc(sizeof(Matrix)); 

    Matrix *ma = *ma_ptr; 
    ma->rows=m; 
    ma->cols=n; 
    ma->element=malloc(m*sizeof(int*)); 
    for(i=0;i<m;i++) 
    { 
     ma->element[i]=malloc(n*sizeof(int)); 
    } 
} 

, а затем вызвать этот метод с адресом переменной, где вы хотите сохранить свою матрицу.

Matrix *m; 
matrixInit(&m, 4, 4); 

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

ma = (Matrix*)malloc(sizeof(Matrix)); 

Тогда вы передаёте указатель на Matrix, но вы должны убедиться, что он указует на матричную структуру. Вы можете сделать это, объявив переменную и вызывая malloc() вне функции (и тем самым распределяя ее по куче), или объявите переменную типа Matrix (и выделите ее в стеке).

Matrix ma; 
matrixInit(&ma, 4, 4); 
+0

Ваш код работает хорошо, но я делаю это для задания, и нам было сказано, что функция имеет указатель на матрицу, а не двойной указатель. – user3075598

+0

А я вижу, и я полагаю, вы тоже не можете вернуть указатель? – pepo

+0

Вы можете добиться этого, удалив выделение из функции, объявив «Матрица m» и вызывая функцию с помощью '& m'. – pepo

1

В C каждый аргумент функции передается по значению. Это означает, что когда вы даете аргумент функции, в качестве аргумента в функции передается копия значения (а не самого значения). Сюда входят указатели - вы можете изменить то, на что ссылается указатель, и не имеют проблем, но если вы укажете указатель на что-то еще в функции, это изменение применимо только к локальной копии указателя.

ma=(Matrix*)malloc(sizeof(Matrix)); 

Здесь, вместо того, чтобы точка ввода указателя на вновь выделенную память для Matrix структуры, вы на самом деле перезаписи локального указателя ma с новым, не делая ничего, чтобы указатель ввода. Это вызывает проблему. Чтобы исправить это, вы можете вернуть указатель на ma.

+0

спасибо! Теперь я понимаю, почему это произойдет. Но есть ли способ доступа к матрице, созданной в функции, без изменения параметров функции? – user3075598

+0

Если вы вернете указатель на недавно выделенную «матрицу», вам не нужно изменять параметры (хотя первый аргумент, который по существу является выходным параметром, бесполезен, если вы тоже возвращаете материал). В качестве альтернативы вы можете передать «Matrix **» в качестве первого аргумента и изменить «Матрицу», на которую он ссылается внутри функции. – kviiri

0

Вы хотите передать указатель на указатель в матрицу, чтобы указатель malloced был доступен для вызывающего. Как это:

void matrixInit (Matrix ** ma, int m, int n) 
{ 
    *ma = malloc(sizeof **ma); // sizeof **ma == sizeof(Matrix) 

Затем вызовите его с этим:

Matrix * matx; 
matrixInit(&matx, 3, 4); 
0

Ваша функция не возвращает матрицу, он создает. Сделайте это вместо этого.

Matrix * matrixInit (int m, int n) 
{ 
    Matrix* ma; 
    int i; 
    ma=(Matrix*)malloc(sizeof(Matrix)); 
    ... 
    return ma; 
} 

... и затем использовать его таким образом

Matrix * myMatrix; 
myMatrix = matrixInit(8,8); // chessboard 
Смежные вопросы