동적메모리 할당받은 메모리를 free() 할때요,
글쓴이: ukyoukyo / 작성시간: 월, 2011/01/10 - 2:51오후
free() 함수에 대한 질문입니다.
free( (void *)ptr );
위와 같이 사용하면 된다는건 알고 있는데요,
ptr은 반드시 동적메모리 할당받은 포인터여야만 해제가 된다고 알고 있습니다.
프로그래머가 귀찮거나 좀 멍청해서(=저 같이^^), 동적메모리 할당받은 포인터가 아닌
일반 포인터 변수인 ptr을 해제하면 seg' fault가 발생하던데요,
free() 함수를 wrapping해서 동적메모리 할당받은 경우에만 free()가 실행되도록 하는 방법은 없을까요 ?
Forums:


메모리 할당 관련 함수를 전부 새로 만들지 않는 이상
메모리 할당 관련 함수를 전부 새로 만들지 않는 이상 불가능합니다.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
glibc 에선 MALLOC_CHECK_ 환경변수
glibc 에선 MALLOC_CHECK_ 환경변수 조작으로 메모리 할당 관련 함수를 전부 새로 만드는 것과 같은 효과를 낼 수 있습니다.
silent ignore, warning only, abort only, warning+abort 네 단계로 조정가능하고, 리눅스 배포본에 따라 기본값이 좀 다릅니다.
glibc 에서 메모리 할당 관련 함수를 전부 새로 만들어보시려면,
http://www.gnu.org/s/libc/manual/html_node/Hooks-for-Malloc.html 에서 시작하시면 됩니다.
cinsk님, bushi님 조언 감사합니다.
cinsk님, bushi님 조언 감사합니다.
진짜 많은 도움되었습니다.
------------------ System programmer...^^
__free_hook
GNU/Linux 환경을 가정하고, 단순히 정적으로 할당된 영역 만을 보호하려고 한다면
__free_hook을 작성해서 넘어온 포인터의 주소를 비교하는 것으로 구현할 수 있을 것 같습니다.
부끄럽지만 간략하게 구현해 본 소스를 올려드리니 참고하시기 바랍니다.
(우분투 10.04.1 x86_64 환경에서 테스트 했습니다.)
#include <stdio.h> #include <stdlib.h> #include <malloc.h> #include <assert.h> #include <unistd.h> #include <fcntl.h> #include <sys/uio.h> #include <elf.h> static unsigned long sdata, edata; static void (*orig_free_hook)(void *, const void *); void free_hook(void *ptr, const void *caller) { unsigned long addr = (unsigned long) ptr; caller = caller; /* to make gcc happy */ if (sdata <= addr && addr <= edata) { puts("try to free static data.. ignored"); return; } __free_hook = orig_free_hook; free(ptr); __free_hook = free_hook; } static void find_data_segment(void) { int fd; Elf64_Phdr *header = NULL; unsigned long type, value, pnum; struct iovec iov[2] = { { &type, sizeof(type) }, { &value, sizeof(value) } }; fd = open("/proc/self/auxv", O_RDONLY); /* auxiliary vector */ do { readv(fd, iov, 2); if (type == AT_PHDR) /* start address of ELF program header */ header = (Elf64_Phdr *) value; else if (type == AT_PHNUM) /* number of header entries */ pnum = value; } while (type); assert(header); while (pnum--) { /* data segment will be "loaded" into memory and "writable" */ if ((header->p_type == PT_LOAD) && (header->p_flags & PF_W)) { sdata = (unsigned long) header->p_vaddr; edata = sdata + header->p_memsz; } header++; } assert(sdata); close(fd); } static void malloc_init(void) { orig_free_hook = __free_hook; __free_hook = free_hook; find_data_segment(); } void (*__malloc_initialize_hook)(void) = malloc_init; char buf1[1]; int main(void) { void *ptr = malloc(1); static int buf2[2]; free(buf1); /* ignored */ free(buf2); /* ignored */ free(ptr); return 0; }pastime님 감사합니다.
pastime님의 홈페이지도 간혹 들려서 많이 참고하고 있어요^^
------------------ System programmer...^^
댓글 달기