2016-04-20 4 views
3

Итак, я прочитал десятки примеров передачи указателя 2D-массива для функции получения/изменения значений этого массива в функции. Но возможно ли создать (выделить память) внутри функции. Что-то вроде этого:Создайте 2D-массив, передав указатель на функцию в c

#include <stdio.h> 

void createArr(int** arrPtr, int x, int y); 

int main() { 

    int x, y;  //Dimension 
    int i, j;  //Loop indexes 
    int** arr;  //2D array pointer 
    arr = NULL; 
    x=3; 
    y=4; 

    createArr(arr, x, y); 

    for (i = 0; i < x; ++i) { 
     for (j = 0; j < y; ++j) { 
      printf("%d\n", arr[i][j]); 
     } 
     printf("\n"); 
    } 
    _getch();  
} 

void createArr(int** arrPtr, int x, int y) { 
    int i, j;  //Loop indexes 
    arrPtr = malloc(x*sizeof(int*)); 
    for (i = 0; i < x; ++i) 
     arrPtr[i] = malloc(y*sizeof(int)); 

    for (i = 0; i < x; ++i) { 
     for (j = 0; j < y; ++j) { 
      arrPtr[i][j] = i + j; 
     } 
    }  
} 
+0

Да, это возможно. – Martin

+0

В вашем коде нет указателей массивов, а также никаких 2D-массивов. – Lundin

+0

@Martin Не могли бы вы рассказать мне, как? – Marcin

ответ

2

Да, передавая указатель на int ** (но 3 звезды считается плохим стилем), я предлагаю, чтобы вернуть выделенную переменную из вашей функции:

int **createArr(int x, int y) 
{ 
    int **arrPtr; 
    int i, j;  //Loop indexes 

    arrPtr = malloc(x*sizeof(int*)); 
    if (arrPtr == NULL) { /* always check the return of malloc */ 
     perror("malloc"); 
     exit(EXIT_FAILURE); 
    } 
    for (i = 0; i < x; ++i) { 
     arrPtr[i] = malloc(y*sizeof(int)); 
     if (arrPtr[i] == NULL) { 
      perror("malloc"); 
      exit(EXIT_FAILURE); 
     } 
    } 
    for (i = 0; i < x; ++i) { 
     for (j = 0; j < y; ++j) { 
      arrPtr[i][j] = i + j; 
     } 
    } 
    return arrPtr; 
} 

вызова его с помощью:

arr = createArr(x, y); 
+2

Вы должны проверить все возвращаемые значения 'malloc', а не только первые. – mch

+1

Нет причин создавать сегментированный указатель на указатель. Вместо этого, если вам нужен 2D-массив, используйте 2D-массив. – Lundin

+0

Soo .. Я могу сделать это вот так: void createArr (int *** arrPtr, int x, int y); И здесь arrPtr - это указатель, который указывает на ** int, который может содержать адреса для массивов. Но это выглядит плохо. И еще один способ, более элегантный, тот, который вы показали. Большое спасибо за быстрые ответы! – Marcin

0

Да, массив можно инициализировать таким образом. Пока вы передаете указатель, адрес памяти должен оставаться неизменным. Итак, если вы присвоите что-либо указателю, оно будет действительным.

думать о а [], как * указатель на первый элемент

а [] [] будет ** указатель на указатель первого элемента или указатель на массив первой (первая строка таблицы)

3

Забудьте о указателях-указателях. Они не имеют ничего общего с 2D-массивами.

Как это правильно: How do I correctly set up, access, and free a multidimensional array in C?.

Одна из многих причин, по которой неправильно использовать указатель на указатель: Why do I need to use type** to point to type*?.

Пример того, как вы могли бы сделать это правильно:

#include <stdio.h> 
#include <stdlib.h> 


void* create_2D_array (size_t x, size_t y) 
{ 
    int (*array)[y] = malloc(sizeof(int[x][y])); 

    for (size_t i = 0; i < x; ++i) 
    { 
    for (size_t j = 0; j < y; ++j) 
    { 
     array[i][j] = (int)(i + j); 
    } 
    } 

    return array; 
} 

void print_2D_array (size_t x, size_t y, int array[x][y]) 
{ 
    for (size_t i = 0; i < x; ++i) 
    { 
    for (size_t j = 0; j < y; ++j) 
    { 
     printf("%d ", array[i][j]); 
    } 
    printf("\n"); 
    } 
} 


int main (void) 
{ 
    size_t x = 5; 
    size_t y = 3; 

    int (*arr_2D)[y]; 

    arr_2D = create_2D_array(x, y); 

    print_2D_array(x, y, arr_2D); 

    free(arr_2D); 

    return 0; 
} 
+1

Когда я пытаюсь использовать вашу версию, он говорит, что: 10 выражение size_t y должно иметь постоянное значение. Поэтому вы не можете делать такие массивы, как это динамически (как я уже сказал ...) – Marcin

+1

@Marcin Я скомпилировал и протестировал этот код. Вы должны использовать компилятор, созданный после 1999 года (почему бы и нет?). Например, GCC. Вы можете указать GCC быть компилятором C с параметрами компилятора 'gcc -std = c11 -pedantic-errors'. – Lundin

+0

Я провел целый день сегодня и не могу понять, что один думает. Все, от ваших швов, чтобы работать, но я не могу понять это. Если я печатаю таблицу по функции 'print2DArray (xDim, yDim, arr),' я получаю все элементы, поэтому он отлично работает. Если я напечатаю один элемент, подобный этому 'printf («% d \ n », arr [0] [0]), это нормально. НО, если я напечатаю так: 'printf ("% d \ n ", old [1] [1]);" или любое другое значение, отличное от 0, я получаю ошибку сегментации. Пожалуйста, помогите мне. – Marcin

Смежные вопросы