2008-09-19 16 views
6

메모리 누수가 발생하지 않고 int 행렬을 생성하는 데 문제가 있습니다. read_matrix()를 통해 동적으로 주어진 크기의 전역 행렬을 만들 수 있기를 원합니다. 그러나 그때 나는 나중에 기억을 풀 수 있기를 원한다. 그래서 내 메인 메소드에서 두번째 printf는 어떤 메모리도 할당되어서는 안되기 때문에 버스 오류가 발생한다. 이걸 어떻게 만들까요?C에서 포인터가있는 int 행렬 - 메모리 할당 혼동

int**  first_matrix; 
int**  second_matrix; 
int**  result_matrix; 

int** read_matrix(int size_x, int size_y) 
{ 
    int** matrix; 
    matrix = calloc(size_x, sizeof(int*)); 
    for(int i = 0;i<size_x;i++) { 
     matrix[i] = calloc(size_y, sizeof(int)); 
    } 
    for(int i = 0;i<size_x;i++) { 
     for(int j = 0;j<size_y;j++) { 
      matrix[i][j] = i*10+j; 
     } 
    } 
    return matrix; 
} 

int main(int stackc, char** stack) 
{ 
    first_matrix = read_matrix(10,10); 
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]); 
    free(*first_matrix); 
    free(first_matrix); 
    printf("9:3 %d - 4:6 %d \n", first_matrix[9][3], first_matrix[4][6]); 
} 

답변

9

메모리가 자유롭게 사용 되었기 때문에 액세스 할 수 없다는 의미는 아닙니다. 물론, 은 매우 불량한데 아이디어는 free'd 이후에 액세스 할 수 있습니다. 그러나 그것이 귀하의 예에서 효과가있는 이유입니다.

free(*first_matrix)은 무료 배열 인 first_matrix[0]이며 다른 배열은 포함하지 않습니다. 마지막 배열을 나타 내기 위해 어떤 종류의 표식이 필요할 것입니다. (외부 배열을 해제 할 때 항상 할당 한 내부 배열 수를 알 수 없다면).당신이 그들을 자유롭게하고 다음

int** read_matrix(int size_x, int size_y) 
{ 
    int** matrix; 
    matrix = calloc(size_x, 1+sizeof(int*)); // alloc one extra ptr 
    for(int i = 0;i<size_x;i++) { 
     matrix[i] = calloc(size_y, sizeof(int)); 
    } 
    matrix[size_x] = NULL; // set the extra ptr to NULL 
    for(int i = 0;i<size_x;i++) { 
     for(int j = 0;j<size_y;j++) { 
      matrix[i][j] = i*10+j; 
     } 
    } 
    return matrix; 
} 

: 같은 뭔가

// keep looping until you find the NULL one 
for(int i=0; first_matrix[i] != NULL; i++) { 
    free(first_matrix[i]); 
} 
free(first_matrix); 
+0

matrix [i]! = NULL까지 루핑하는 것이 NULL에 마지막 포인터를 설정하지 않아도 작동하는 것 같습니다. 우연의 일치인가요? 다른 나쁜 것입니까? – Fredrik

+0

하나의 여분의 포인터를 할당하고 그것을 설정하지 않으면 OS에 따라 NULL이 기본 * 될 수 있습니다 (Windows는 할당 된 메모리를 0으로 만듭니다. Unix는 그렇지 않습니다). 그렇지 않은 경우 할당 된 배열의 끝에서 벗어나서 NULL 포인터 또는 충돌 가능성이 높아지기 전까지는 해제 상태를 유지합니다. –

+1

calloc은 항상 메모리를 null로 설정합니다. – quinmars

2

는 개별적으로 각 행을 확보해야합니다


void free_matrix(int **matrix, int size_x) 
{ 
    for(int i = 0; i < size_x; i++) 
     free(matrix[i]); 
    free(matrix); 
} 
+0

C의주기에 변수를 선언 할 수 없습니다. – terminus

+2

C99에서는 할 수 있지만 코드는 다시 이식 할 수 없습니다. –

0

는 당신은 first_matrix의 첫 번째 행 (또는 열)을 해제. 다음과 같은 또 다른 함수를 작성하십시오 :

void free_matrix(int **matrix, int rows) 
{ 
    int i; 
    for(i=0; i<rows; i++) 
    { 
     free(matrix[i]); 
    } 
    free(matrix); 
} 

행렬을 저장하기 위해 행렬을 구조체로 만들 수 있습니다.

1

메모리를 확보해도 메모리가 사라지지 않는다고해도 다른 할당이 동일한 메모리 덩어리를 차지할 수 있습니다. 당신이 무엇을 넣었는지 다른 것이 그것을 덮어 쓸 때까지 여전히 거기에있게 될 것입니다.

또한 할당 한 모든 항목을 비우지 않아도됩니다. 포인터 배열과 첫 번째 행만 해제하면됩니다. 그러나 모든 것을 올바르게 해버 리더라도 여전히 동일한 효과를 얻을 수 있습니다.

"버스 오류"를 만들려면 프로세스에 속하지 않는 메모리를 가리켜 야합니다. 어쨌든 왜 그걸하고 싶니?

+0

나는 메모리가 자유 였다는 것을 보여 주기만을 원했지만, 내가 생각하기에 그 잘못이 내 생각에 있었음을 배웠고, onOS X 이후로 valgrind를 실행할 수없고, 내가 정말로 해방했는지를 알기위한 방법을 원했다. – Fredrik

0

버스 오류 발생을 방지하는 대신 unfree'd 메모리를 추적하는 데 valgrind를 사용하는 것이 좋습니다. 그것은 많은 다른 물건을 위해 또한 흔드는 다.

샘은 n 번째 행에 대한 행렬의 첫 번째 행과 행의 목록 만 1 없음을 확보하고 있기 때문에 당신은 메모리 누수를 받고있어

+0

나는 OS X에있어 valgrind를 실행할 수 없다. 그렇지 않으면 나는/ Mac에서 작동하는 다른 방법을 알고 있는가? – Fredrik

0

. 무료로 전화해야합니다.

그러나, 대안의 몇 가지가 있습니다 -는 sizeof (INT의 *) 행 + 행 COLS *를 sizeof (int)를 바이트를 할당하고 행 포인터의 첫 번째 바이트를 사용합니다. 그런 식으로, 당신은 오직 하나의 메모리 덩어리를 자유롭게 할 수있다. (그리고 할당 자도 더 쉽다.) - 행수를 포함하는 구조체를 사용한다. 그런 다음 행 목록을 모두 피할 수 있습니다 (메모리 절약). 유일한 단점은 행렬을 처리하기 위해 함수, 매크로 또는 지저분한 표기법을 사용해야한다는 것입니다.

두 번째 옵션을 사용하면 모든 C99 컴파일러에서 이와 같은 구조체를 사용할 수 있으며 다시 한 번 메모리 (size numints * sizeof (int) + sizeof (int))를 할당하면됩니다. :

struct matrix { 
    int rows; 
    int data[0]; 
} 
0

여기에 누락 개념, 모든은 calloc을 위해, 무료로이 있어야한다는 것입니다. 이며 free는 calloc에서 전달 된 포인터에 적용되어야합니다.

난 당신이 여기에

에 할당 포인터를 모두 무료로 루프를 사용 를 함수 (이름 delete_matrix)을 생성하는 것이 좋습니다 (내가 < size_x, 나는 = 0을 int로 내가 ++) { matrix [i] = calloc (size_y, sizeof (int)); }

그런 다음이 작업이 완료되면이 할당 된 포인터를 해제하십시오.

매트릭스 = calloc (size_x, sizeof (int *));

당신이 지금하고있는 방법,

무료 (* first_matrix); 무료 (first_matrix);

당신이 원하는대로 할 수 없습니다.