2015-11-19 2 views
4

Я пытался сделать динамическую 5x5 целочисленного массиваКак я могу использовать динамический 2d массив в с

int **data=malloc(5*5); 

Но я получаю ошибку сегментации при попытке доступа к нему.

+0

Это будет выделять только 25 байт. Если вы хотите, чтобы ваш массив удерживал 25 целых чисел, умножьте на sizeof int. – bruceg

ответ

7

Вам нужно выделить память для 2d-массива, который вы хотите сделать (что, я думаю, вы понимаете). Но сначала вам нужно будет выделить пространство для указателей, где вы будете хранить строки 2D-массива.

int **data=(int**)malloc(sizeof(*data)*5); //Here 5 is the number of rows 

Теперь вы можете выделить место для каждой строки.

for(int r=0;r<5;r++){ 
    data[r]=(int*)malloc(sizeof(**data)*5);//here 5 is the width of the array 
} 

Если вы хотите непрерывный блок памяти для всего массива, вы можете выделить один размерный массив размера 25, и получить доступ к нему, как data[r*5+c].

PS: Вместо sizeof(*data) и sizeof(**data), вы можете использовать sizeof(int*) и sizeof(int), чтобы избежать путаницы с *

PS: Если вы не используете C++, снимая слепки из возвращаемого значения из таНос лучше (см комментарии) ,

+0

Спасибо за помощь! –

+5

литье результата 'malloc' не рекомендуется и не нужно –

+0

почему это не рекомендуется? –

4

Если вы хотите один блок непрерывной памяти для хранения 5х5 = 25 целых чисел:

int *data = malloc(5*5*sizeof(*data)); 

Если вы хотите 2d массив размером 5x5

int **data = malloc(5*sizeof(*data)); 
for (int i=0; i<5; ++i) 
    data[i] = malloc(5*sizeof(**data)); 
3

Есть две возможности. Первые из них действительно выделить двумерный массив:

int (*data)[5] = malloc(5 * 5 * sizeof(int)); 

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

Второй заключается в том, чтобы сначала выделить одномерный массив указателей, а затем выделить одномерные массивы, на которые указывают уже выделенные указатели.

Например

int **data = malloc(5 * sizeof(int *)); 
for (size_t i = 0; i < 5; i++) 
{ 
    data[i] = malloc(5 * sizeof(int)); 
} 

В этом случае выделяются на самом деле 6 экстентов памяти: один для массива указателей и других 5 для массивов целых чисел.

Чтобы освободить выделенную память в первом примере достаточно написать

free(data); 

и во втором примере, вам нужно написать следующее

for (size_t i = 0; i < 5; i++) free(data[i]); 
free(data); 
-1

Вот ответ:

int ** squaredMatrix; 
int szMatrix=10; 
squaredMatrix= (int**)malloc(szMatrix*sizeof(int*)); 

для создания 2d массивов вы должны рассматривать их как один массив, каждый блок которого представляет собой массив a усиление . enter image description here

, например, в изображении выше, синие блоки делают массив, который каждый из синего блока указывает на массив (каждые 4 зеленых блоков в строке являются массивом и синие блоки в столбце являются основной массив)

+0

Ваш код не выделяет память, как показано на рисунке. – this

+0

@this, я не говорю, что картина имеет отношение к коду, описание для изображения находится ниже. –

+0

Я говорил, что ваш код неправильный. – this

0

Если вы хотите обработать массив как 2D массива (a[i][j]) и вы хотите, чтобы все элементы массива должны быть смежными в памяти, выполните следующие действия:

int (*data)[5] = malloc(sizeof *data * 5); 

Если вы хотите быть таблицы определить размер массива во время выполнения и ваш компилятор поддерживает массивы переменной длины :

size_t rows, cols; 
...  
int (*data)[rows] = malloc(sizeof *data * cols);2 

Если ваш компилятор не поддержки Власом и вы все еще хотите, чтобы определить размер массива во время выполнения, вы могли бы сделать:

size_t rows, cols; 
... 
int **data = malloc(sizeof *data * rows); 
if (data) 
{ 
    for (size_t i = 0; i < rows; i++) 
    { 
    data[i] = malloc(sizeof *data[i] * cols); 
    } 
} 

Недостатком этого подхода является то, что строки массива не гарантируют непрерывности в памяти (их скорее всего не будет). Элементы в пределах одна строка будет смежной, но строки не будут смежными друг с другом.

Если вы хотите, чтобы определить размер массива во время выполнения и есть все элементы массива должны быть смежными в памяти но ваш компилятор не поддерживает массивы переменной длины, вам нужно будет выделить 1D массив и вручную вычислить ваши показатели (a[i * rows + j]):

int *data = malloc(sizeof *data * rows * cols); 


1. Влас были введены с C99, но необязательными в C2011. Компилятор post-C99, который делает не, определяет макрос __STDC_NO_VLA__ должен поддерживать VLA.

2. Осторожно - есть ли вопрос, является ли sizeof *data хорошо определенным в этом примере; выражение sizeof обычно оценивается во время компиляции, но когда операндом является VLA, выражение оценивается во время выполнения. data не указывает на что-либо еще, и попытка разыменования неверного указателя ведет к неопределенному поведению. Все, что я могу сказать, это то, что я много использовал эту идиому и никогда не имел проблемы, но это может быть связано скорее с неудачей, чем с дизайном.

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