2013-03-08 2 views
6

프로젝트 중간에 있으며 malloc()realloc()을 사용하려고합니다. 내가 malloc 할 때 알아, 작동하지만 realloc 사용할 때 할당 된 메모리의 양을 전혀 변경하지 않습니다. 나는 항상 realloc이 이미 할당 된 메모리를 다시 할당 할지라도 항상 그랬다.메모리가 다시 할당되지 않습니다.

이 포함 : 내가 malloc에를 사용하는 구조체 (7)을 할 때 나는 것,

struct student { 
    int age; 
    int numOfClasses; 
    int gender; //0 male; 1 female 
} student; 

:

#include <stdlib.h> 

내가 구조체가 여기에

내가 가진 무엇 다음 코드 줄을 사용하십시오.

student stud* = (structure*) malloc(7*sizeof(student)); 

이 줄이 작동합니다. 이 코드 줄은 구조체의 크기를 7로 곱합니다. 즉, 7 개의 구조체 배열을 만들기에 충분한 메모리를 확보하게됩니다. 다음은

enter image description here

: 나는 팔에 그 변경하려는 경우 A 이전 malloc으로 할당 된 메모리이며, B 새로운 malloc으로 할당 된 (또는 realloced) 메모리입니다

지금, 나는이 작업을 수행 할 것 나는 코드에서 얼마나 : 내가 아는 바로는

stud = (student*)realloc(stud, 8*sizeof(student)); 

는 realloc을 두 번째 매개 변수에 변수를 받아서 메모리의 양을 mallocs. 그런 다음 포인터 (또는 이전의 malloced)를 가져 와서 지정된 포인터에서 가능한 한 많이 메모리에 채 웁니다. 물론 두 번째 매개 변수는 이전의 malloced 크기보다 커야합니다. 그렇지 않으면 stud은 결국 일부 메모리를 잃게됩니다. 이제 이것이 내 문제입니다. 위의 줄을 호출하면 아무 것도 변경되지 않습니다. malloced 배열은 여전히 ​​길이가 7입니다. 나는 realloc할만한 충분한 메모리가 있음을 확신합니다.

내가이 일을 제대로하고 있습니까? 내 문제는 어디에있을 수 있습니까?

+8

malloced 배열의 길이가 여전히 7이라고 생각하십니까? –

+0

이것은 여러분의 문제와 관련이 없지만, 여러분의 구조가'enum'을 완벽하게 사용한다고 생각합니다. – teppic

답변

11

realloc 님의 이해는 거의 정확합니다. 에 다른 포인터를 반환하는이 없습니다. 초기 블록 이후에 사용되지 않은 메모리가 충분히 남아있을 수 있으므로 힙 관리자는 동일한 포인터를 반환 할 수 있습니다 (그러나 블록이 더 커지는 것을 알 수 있도록 자체 내부 상태를 조정합니다).

그래도 작은 실수 하나를 범했습니다.

stud = (student*)realloc(stud, 8*sizeof(student)); 

은 여기 realloc의 반환 값으로 stud 포인터를 대체하고있다. 메모리 부족으로 인해 NULL이 반환되면 원래 stud 포인터가 손실되어 메모리가 누출됩니다. 대신 임시 포인터를 사용해야합니다.

tmp = realloc(stud, 8*sizeof(student)); 
if (tmp) 
    stud = tmp; 

또한 실제로는 여덟 번째 슬롯에 무엇인가 넣어야합니다. realloc 후 8 번째 슬롯은 유효한 할당 된 메모리이지만 의미있는 것을 저장할 때까지 가비지를 포함합니다.

+0

나는 realloc하기에 충분한 메모리가 있다고 확신한다. –

+1

좋아,하지만 malloced 배열의 길이가 여전히 7이라고 생각하는 이유는 아직 설명하지 못했습니다. –

+0

이것이 7에서 8까지 할당하지 않는 이유입니다. –

4

이 나는 ​​이러한 권장 사항을 거라고하지만, 작동합니다 :

는 malloc에의 반환을 캐스팅하지 마십시오. C에서 쓸모가 없으며 <stdlib.h>을 포함하는 것을 잊어 버린 것을 숨길 수 있습니다.

ptr = realloc (ptr, ...)은 realloc이 NULL 인 경우 메모리 누수가 발생하므로 사용하지 마십시오. 대신, 유형이 지적되고하지 포인터를 사용하여 식을 참조 즉,

if ((new_ptr = realloc (stud, 8 * sizeof (*stud))) != NULL) { 
    stud = new_ptr; 
} else { 
    scream_and_die("out of memory"); 
} 

를 사용 sizeof (*stud)을 사용 (당신이 할당 포인터의 특정 유형의 독립합니다). 이렇게하면 typedef의 이름을 바꿀 때 malloc/realloc 행을 수정할 필요가 없습니다. 즉, C의 동적 메모리 할당을위한 모범 사례는 N 개의 유형의 배열에 대해

#include <stdlib.h> 
sometype *ptr; 
... 
ptr = malloc (N * sizeof *ptr); 

입니다.

관련 문제