2012-08-14 1 views
5

견적 :K & R에서 문장의 정확성에 대해 확실치 않은 | 포인터 연산 | 절차를 확보

테스트 경우 (allocbuf + ALLOCSIZE - allocp> = N) { 확인 n 개의 문자에 대한 요구를 만족시키기에 충분한 공간이 있는지. 존재하는 경우, 의 새로운 값 allocp는 allocbuf의 끝을 초과하여 최대 하나가됩니다. 이 관련

코드 :

#define ALLOCSIZE 10000 /* size of available space */ 
static char allocbuf[ALLOCSIZE]; /* storage for alloc */ 
static char *allocp = allocbuf; /* next free position */ 

char *alloc(int n) 
/* return pointer to n characters */ 
{ 
    if (allocbuf + ALLOCSIZE - allocp >= n) { /* it fits */ 
     allocp += n; 
     return allocp - n; /* old p */ 
    } else 
/* not enough room */ 
     return 0; 
} 
void afree(char *p) /* free storage pointed to by p */ 
{ 
    if (p >= allocbuf && p < allocbuf + ALLOCSIZE) 
     allocp = p; 
} 

그래서 어떻게 allocbuf의 마지막 위치 이상으로 할 수 있는가? 내 의견으로는 allocbuf [9999]

그 이상의 것. allocbuf [10000]가 잘못되어 메모리 누수가 발생했습니다. 맞습니까?


질문의 두 번째 부분 - 그 이름대로 그 기능은 배열의 특정 위치에 저장된 값을 삭제하는 것입니다. 그러나 내가 볼 수 있듯이 배열의 왼쪽에 "녹음 헤드"를 몇 군데 움직일 수 있습니까? 거기에 저장된 데이터는 변경되지 않습니다.

+0

+1, 발견. – perilbrain

+1

'allocp'가'allocbuf [10000]'을 가리키면 저장소가 완전히 사용되었다는 것을 의미합니다. 마지막 슬라이스는 정확히'n' 개의 항목을가집니다. 따라서 후속 alloc()은'0'을 반환합니다. 인용문은이 "불법"포인터가 사용되도록 허용되어 있지 않으며 실제로'alloc()'에서 반환되지 않는다고 말합니다. – evnu

+2

FYI는 너를 위해 할당 된 너비보다 큰 메모리에 액세스하는 것이 오버런이며 메모리 누수는 아닙니다. 메모리 누수가 발생하면 할당 된 메모리의 트랙이 손실되어 나중에 해당 메모리를 해제 할 수 없습니다. –

답변

5

allocp은 항상 마지막 자유 메모리 위치를 가리켜 야하지만 메모리 위치가없는 경우는 allocbuf 끝을 벗어난 위치가됩니다.

단일 메모리 셀만 버퍼에 남아있는 상황을 고려하십시오. allocp은 마지막 사용 가능한 메모리 셀이므로 allocbuffer[9999]을 가리 킵니다. 당신은 함수 호출 alloc(1) 시험을 할 때 당신이 한 char를 할당하려고 한 char 왼쪽 정확히 있기 때문에 정상적으로 지금

allocbuf + ALLOCSIZE - allocp >= n 

는 true를 돌려줍니다. 그런 다음 가장 마지막 메모리 위치가 할당됩니다. 지금은 allocbuf - allocp == ALLOCSIZE이며 allocbuf 끝을 넘은 사람입니다. 그러나이 경우 위에서 언급 한 테스트는 항상 false를 반환하므로 allocbuf 범위를 벗어난 메모리는 액세스 할 수 없습니다. afree에 관한 질문에 대해


: malloc에 의해 반환 된 메모리의 초기 값은 정의되지 않습니다. 이것은 당신이 그것에 대해 어떠한 가정도 할 수 없으며 사용하기 전에 그것을 덮어 써야한다는 것을 의미합니다. 따라서 afree은 사용자가 가정하고있는 것과 반대되는 데이터를 삭제할 필요가 없습니다. 더 이상 사용되지 않고 나중에 할당 할 수 있도록 표시하는 것이 좋습니다.

보조 메모에는 malloc이라는 이름의 calloc과 매우 비슷한 기능이 있는데, 요청 된 메모리 블록을 할당 한 후 모두 0으로 초기화됩니다. 두 번째 질문의 일부에 대해서는

+1

배열 끝에 도달 한 요소 1에 대한 포인터가 허용됩니다. – ecatmur

+0

@paldepind - 정말 고마워! 무료 절차에 관한 두 번째 부분에도 답할 수 있습니까? –

+0

당신을 환영합니다! 답변을 업데이트했습니다. – paldepind

2

: 메모리 관리 기능 afree() 같은 또는 C 라이브러리 free()하지 일반적으로 없거나 명확 기억을한다. 그들은 단지 재사용을 가능하게합니다. 당신이 성과 비용을 지불하지 않기 때문에 이것은 좋다. 불행히도, 더 이상 소유하지 않은 메모리를 사용하는 것과 같은 버그를 숨길 수 있습니다.

보안상의 이유로 또는 디버깅을 지원하기 위해 free()을 호출 할 때 일부 힙 관리자는 메모리를 0으로 만들거나 특별한 값으로 채울 수 있습니다. 이것은 표준에서는 필요하지 않으며 특별히이 동작을 활성화해야합니다.