문제

나는 배열 배열을 동적으로 할당하는 것과 같은 C의 몇 가지 기본 사항을 정말로 이해하지 못합니다.나는 당신이 할 수 있다는 것을 알고 있습니다:

int **m;

2차원 배열을 선언하기 위해(나중에 *alloc 함수를 사용하여 할당됨)또한 다음을 수행하여 "쉽게" 액세스할 수 있습니다. *(*(m + line) + column).하지만 해당 배열의 요소에 값을 어떻게 할당해야 합니까?gcc를 사용하여 다음 문 m[line][column] = 12; 분할 오류로 인해 실패합니다.

모든 기사/문서를 높이 평가하겠습니다.:-)

도움이 되었습니까?

해결책

그만큼 m[line][column] = 12 구문은 정상입니다 (제공됩니다 line 그리고 column 범위에 있습니다).

그러나 할당하는 데 사용하는 코드를 작성하지 않았으므로 잘못되었는지 여부를 얻기가 어렵습니다. 그것은 줄을 따라 무언가가되어야합니다

m = (int**)malloc(nlines * sizeof(int*));

for(i = 0; i < nlines; i++)
  m[i] = (int*)malloc(ncolumns * sizeof(int));

일부 측면 노트 :

  • 이런 식으로 각 라인을 다른 길이로 할당 할 수 있습니다 (예 : 삼각 배열).
  • 배열을 사용하는 동안 나중에 개별 라인을 Realloc () 또는 free () 할 수 있습니다.
  • 무료 () 무료 () 전체 배열 () 전체 배열을 무료로 사용해야합니다.

다른 팁

m[line][colummn] 구문이 정확합니다.하지만 C에서 2차원 배열을 사용하려면 메모리를 할당해야 합니다.예를 들어 이 코드는 주어진 행과 열의 테이블에 메모리를 할당합니다.

int** AllocateArray(int line, int column) {
  int** pArray = (int**)malloc(line*sizeof(int*));
  for ( int i = 0; i < line; i++ ) {
    pArray[i] = (int*)malloc(column*sizeof(int));
  }
  return pArray;
}

간결성을 위해 malloc에 ​​대한 오류 검사를 생략했습니다.실제 솔루션에는 이러한 기능이 포함되어야 합니다.

2D 배열이 아닙니다. 배열 배열이므로 여러 할당이 필요합니다.

다음은 수정 된 버전입니다 Quinmars의 솔루션 단일 메모리 블록 만 할당되며 의례에 따라 일반적인 값으로 사용할 수 있습니다. void *:

#include <stdlib.h>
#include <string.h>
#include <assert.h>

void ** array2d(size_t rows, size_t cols, size_t value_size)
{
    size_t index_size = sizeof(void *) * rows;
    size_t store_size = value_size * rows * cols;

    char * a = malloc(index_size + store_size);
    if(!a) return NULL;

    memset(a + index_size, 0, store_size);
    for(size_t i = 0; i < rows; ++i)
        ((void **)a)[i] = a + index_size + i * cols * value_size;

    return (void **)a;
}

int printf(const char *, ...);

int main()
{
    int ** a = (int **)array2d(5, 5, sizeof(int));
    assert(a);
    a[4][3] = 42;
    printf("%i\n", a[4][3]);
    free(a);
    return 0;
}

캐스팅하는 것이 정말 안전한 지 잘 모르겠습니다. void ** 에게 int ** (표준으로 인해 변환 할 때 변환이 발생할 수 있다고 생각합니다. void * ?), 그러나 그것은 GCC에서 작동합니다. 안전한면에 있으려면 모든 발생을 대체해야합니다. void * ~와 함께 int * ...


다음 매크로는 이전 알고리즘의 유형-안전 버전을 구현합니다.

#define alloc_array2d(TYPE, ROWS, COLS) \
    calloc(sizeof(TYPE *) * ROWS + sizeof(TYPE) * ROWS * COLS, 1)

#define init_array2d(ARRAY, TYPE, ROWS, COLS) \
    do { for(int i = 0; i < ROWS; ++i) \
        ARRAY[i] = (TYPE *)(((char *)ARRAY) + sizeof(TYPE *) * ROWS + \
        i * COLS * sizeof(TYPE)); } while(0)

다음과 같이 사용하십시오.

int ** a = alloc_array2d(int, 5, 5);
init_array2d(a, int, 5, 5);
a[4][3] = 42;

다른 답변에 동의하지만 Malloc은 매우 느리기 때문에 대부분의 경우 전체 배열을 한 번에 할당하는 것이 좋습니다.


int **
array_new(size_t rows, size_t cols)
{
    int **array2d, **end, **cur;
    int *array;

    cur = array2d = malloc(rows * sizeof(int *));
    if (!array2d)
        return NULL;

    array = malloc(rows * cols * sizeof(int));
    if (!array)
    {
        free(array2d);
        return NULL;
    }

    end = array2d + rows;
    while (cur != end)
    {
        *cur = array;
        array += cols;
        cur++;
    }

    return array2d;
}

배열을 풀려면 단순히 다음과 같습니다. free(*array); free(array);

참고 :이 솔루션은 행의 순서를 변경하지 않으려는 경우에만 작동합니다. 그런 다음 첫 번째 요소의 주소를 잃어 버릴 수 있기 때문에 나중에 배열을 제거해야합니다.

험. 옵션으로 구식 연기와 거울은 어떻습니까?

#define ROWS  5
#define COLS 13
#define X(R, C) *(p + ((R) * ROWS) + (C))

int main(void)
{
    int *p = (int *) malloc (ROWS * COLS * sizeof(int));
    if (p != NULL)
    {
        size_t r;
        size_t c;
        for (r = 0; r < ROWS; r++)
        {
            for (c = 0; c < COLS; c++)
            {
                 X(r,c) = r * c;  /* put some silly value in that position */ 
            }
        }

        /* Then show the contents of the array */ 
        for (r = 0; r < ROWS; r++)
        {
            printf("%d ", r);   /* Show the row number */ 

            for (c = 0; c < COLS; c++)
            {
                 printf("%d", X(r,c));
            }

            printf("\n");
        }

        free(p);
    }
    else
    {
        /* issue some silly error message */ 
    }

    return 0;
}

사용 malloc(3) 첫 번째 배열을 할당하고 malloc(3) 함께 일해야합니다 array[r][c] 그것은 동일해야하기 때문입니다 *(*(array + r) + c), 그것은 C 표준에 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top