2016-01-13 1 views
1

Я хочу выделить память двухмерному массиву типа int, но память должна быть непрерывной.Выделить память для двумерного массива целых чисел, но он должен быть непрерывным

его необходимо освободить, просто позвонив по телефону free(ptr). Мне не нужно будет звонить бесплатно в каждый блок памяти.

+1

Умножьте 'M * N * sizeof (int)' и сделайте 'malloc' для такого блока памяти. M и N - количество элементов в каждом измерении. – i486

ответ

5

Формально это делается так:

int (*arr_ptr) [x][y] = malloc(sizeof(int[x][y])); 

(*arr_ptr)[i][j] = something; // access one element 

free(arr_ptr); 

Однако, это делает доступ к элементам немного неудобно: (*arr_ptr)[i][j] немного трудно читать. Трюк, чтобы избежать этого, чтобы оставить одну размерность указателя массива и вместо того, чтобы рассматривать его как массив одномерных массивов:

int (*arr_ptr) [y] = malloc(sizeof(int[x][y])); 

arr_ptr[i][j] = something; // access one element 

free(arr_ptr); 

Если у вас есть древний компилятор, вы должны создать более некрасиво, «подогнаны» 2D массив:

int* ptr = malloc(sizeof(int) * x * y); 

ptr[i*y + j] = something; // access one element 

free(ptr); 
+0

Действительно классная идея с использованием массивов переменной длины, подобных этому. Для тех, кто не знает, «древний компилятор» означает «pre C99 компилятор», такой как MSVC. – fuz

2

Если ваш компилятор поддерживает массивы переменной длины (Vlas), то вы можете написать следующим образом

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

int main(void) 
{ 
    size_t m = 3; 
    size_t n = 4; 

    int (*a)[n] = malloc(m * n * sizeof(int)); 

    for (size_t i = 0; i < m; i++) 
    { 
     for (size_t j = 0; j < n; j++) a[i][j] = i * n + j; 
    }   

    for (size_t i = 0; i < m; i++) 
    { 
     for (size_t j = 0; j < n; j++) printf("%2d ", a[i][j]); 
     printf("\n"); 
    }   

    free(a); 

    return 0; 
} 

выход программы

0 1 2 3 
4 5 6 7 
8 9 10 11 

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

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

#define N 4 

int main(void) 
{ 
    size_t m = 3; 

    int (*a)[N] = malloc(m * N * sizeof(int)); 

    for (size_t i = 0; i < m; i++) 
    { 
     for (size_t j = 0; j < N; j++) a[i][j] = i * N + j; 
    }   

    for (size_t i = 0; i < m; i++) 
    { 
     for (size_t j = 0; j < N; j++) printf("%2d ", a[i][j]); 
     printf("\n"); 
    }   

    free(a); 

    return 0; 
} 
0

Другая возможность состоит в том, чтобы использовать одномерный массив как двухмерной один, как в следующем примере:

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

#define N 2 
#define M 3 

/* 
    array has N * M elemts: 

    | N | N | N | 
    v   v   v   v 
    |----|----|----|----|----|----| 


    array[i][j] == array[i*N + j] 
*/ 

#define GET(i,j) (i*N + j) 


int main(int argc, char **argv) { 

    int *array; 
    int i, j; 

    array = malloc(N * M *sizeof(int)); 


    for (i = 0; i < N; i++) 
     for (j = 0; j < M; j++) 
      array[i*N + j] = i+j; 

    for (i = 0; i < N; i++) 
     for (j = 0; j < M; j++) 
      printf("array[%d][%d] = %d\n", i, j, array[i*N + j]); 

    printf("Using the macro:\n"); 
    for (i = 0; i < N; i++) 
     for (j = 0; j < M; j++) 
      printf("array[%d][%d] = %d\n", i, j, array[GET(i,j)]); 

    free(array); 

    return 0; 
} 

Я также определил макрос GET(i,j) так, что код будет больше на самом деле это действительно необходимо только для обработки более сложных случаев, чем двухмерных.

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