2016-08-23 3 views
0

3D 배열에 인접한 공간을 할당해야합니다. (수정 :) 나는 첫 번째 장소 에서이 명확하게 했어야하지만, 실제 생산 코드에서, 나는 런타임까지 배열의 크기를 알 수 없습니다. 나는 물건을 단순하게 유지하기 위해 아래 장난감 코드에 상수로 제공했다. 인접한 공간을 주장 할 때 발생할 수있는 잠재적 인 문제점을 알고 있지만 방금 가져야합니다. 2D 배열에서이 작업을 수행하는 방법을 살펴 봤지만 분명히 패턴을 3D로 확장하는 방법을 이해하지 못했습니다. 내가 메모리, free_3d_arr을 확보하기 위해 함수를 호출 할 때 오류가 발생합니다 : 사람이 수정 프로그램이 무엇인지 말해 줄 수 있다면C 배열의 연속적인 메모리 할당

lowest lvl 
mid lvl 
a.out(2248,0x7fff72d37000) malloc: *** error for object 0x7fab1a403310: pointer being freed was not allocated 

은 감사하겠습니다. 코드는 여기에 있습니다 : 당신의 3D 배열에 대한

int (*a)[sz[1]][sz[2]] = calloc(sz[0], sizeof(*a)); 

이 할당 연속 저장 : 당신이 C를 사용하고 있기 때문에, 나는 당신이 진짜 다차원 배열을 사용하는 것이 좋습니다 것입니다

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

int ***calloc_3d_arr(int sizes[3]){ 

    int ***a; 
    int i,j; 

    a = calloc(sizes[0],sizeof(int**)); 
    a[0] = calloc(sizes[0]*sizes[1],sizeof(int*)); 
    a[0][0] = calloc(sizes[0]*sizes[1]*sizes[2],sizeof(int)); 

    for (j=0; j<sizes[0]; j++) { 
     a[j] = (int**)(a[0][0]+sizes[1]*sizes[2]*j); 
     for (i=0; i<sizes[1]; i++) { 
     a[j][i] = (int*)(a[j]) + sizes[2]*i; 
     } 
    } 

    return a; 

} 



void free_3d_arr(int ***arr) { 

    printf("lowest lvl\n"); 
    free(arr[0][0]); 
    printf("mid lvl\n"); 
    free(arr[0]);   // <--- This is a problem line, apparently. 
    printf("highest lvl\n"); 
    free(arr); 

} 



int main() { 

    int ***a; 
    int sz[] = {5,4,3}; 
    int i,j,k; 

    a = calloc_3d_arr(sz); 

    // do stuff with a 

    free_3d_arr(a); 

} 
+1

'a [j] = ...'다음에'a [j] = ...'뒤에 오는 것이 어색하게 보입니다 ... –

+1

3D 배열은 없으며, 하나 또는 하나의 점으로 사용할 수있는 것도 없습니다 당신의 코드! 포인터가 배열이 아닙니다! 3D 배열이 필요한 경우 하나를 사용하십시오! 아, 그리고 3 성급 C 프로그래머가되는 것은 칭찬이 아닙니다. – Olaf

+1

그런데 SO는 크라우드 소스 디버거가 아니기 때문에 직접 디버깅하는 데 투자해야합니다. –

답변

3

. C99 이후의 크기는 동적 일 수 있습니다. 당신처럼 당신은 당신의 포인터 배열을 정확히 배열에 액세스 :

for(int i = 0; i < sz[0]; i++) { 
    for(int j = 0; j < sz[1]; j++) { 
     for(int k = 0; k < sz[2]; k++) { 
      a[i][j][k] = 42; 
     } 
    } 
} 

그러나, 후드 아래에는 포인터 배열이없는, 인덱스는 포인터 연산과 배열 포인터 붕괴의 마법에 의해 이루어집니다. 하나의 calloc()이 일을 할당하는 데 사용 된 이후 그리고, 하나의 free()는 그것을 제거하기에 충분 :

free(a); //that's it. 
+2

Nitpicking : 모든 int는'size_t'이어야합니다. – alk

+1

약간의 추가 : C11은 VLA를 선택적으로 만들었습니다 (주 용의자는 C99 및 C90 호환 비싼 도구를 판매하는 일부 내장형 컴파일러 공급 업체를 지원할 수없는 유명한 회사입니다). 현대 컴파일러가 VLA를 지원할 것이라고 말했습니다. – Olaf

+0

@Bob__ 감사합니다 .-) 나는'calloc()'이'malloc()'이하지 않는 크기 인자를 * 흥미롭게 * 분할하는 것을 사용한다는 것을 항상 잊는다. 그러나 나는 그것을 지금 고쳤다. – cmaster

1

당신은 같은 것을 할 수 있습니다 : 나는 그것을 사용하고 잘 작동

int ***allocateLinearMemory(int x, int y, int z) 
{ 
    int *p = (int*) malloc(x * y * z * sizeof(int)); 
    int ***q = (int***) malloc(x * sizeof(int**)); 
    for (int i = 0; i < x; i++) 
    { 
     q[i] = (int**) malloc(y * sizeof(int*)); 
     for (int j = 0; j < y; j++) 
     { 
      int idx = x*j + x*y*i; 
      q[i][j] = &p[idx]; 
     } 
    } 
    return q; 
} 

void deallocateLinearMemory(int x, int ***q) 
{ 
    free(q[0][0]); 
    for(int i = 0; i < x; i++) 
    { 
     free(q[i]); 
    } 
    free(q);  
} 

합니다.

+0

죄송합니다, 복사 - 붙여 넣기는 C를 알고. –