malloc()을 사용하여 할당된 메모리 블록의 크기를 어떻게 얻을 수 있습니까?[복제하다]

StackOverflow https://stackoverflow.com/questions/1208644

문제

가능한 중복:
C의 포인터에서 배열의 크기를 어떻게 얻을 수 있습니까?
프로그래밍 방식으로 C++ 배열의 크기를 결정할 수 있는 방법이 있습니까?그렇지 않다면 왜 그렇습니까?

C 스타일 함수에서 할당된 메모리 덩어리에 대한 포인터를 얻습니다.이제이 포인터 포인트가 할당 된 메모리 블록이 얼마나 큰지 아는 것은 디버깅 목적으로 정말 흥미로울 것입니다.

맹목적으로 경계를 뛰어넘어 예외를 유발하는 것보다 더 우아한 것이 있을까요?

미리 감사드립니다, Andreas

편집하다:

Windows에서는 VC++2005를 사용하고 Linux에서는 GCC 4.3을 사용합니다.

편집2:

나는 가지고있다 _msize 불행히도 VC ++ 2005에 따라 디버그 모드에서 예외가 발생합니다 ....

편집3:

잘.예외를 제외하고 위에서 설명한 방법을 시도했는데 작동했습니다.적어도 디버깅을하고 라이브러리로 전화를 한 직후에 버퍼 경계를 넘어옵니다.매력처럼 작동합니다.

우아하지도 않고 프로덕션 코드에서는 전혀 사용할 수 없습니다.

도움이 되었습니까?

해결책

표준은 아니지만 도서관이 msize() 크기를 줄 함수.

일반적인 해결책은 포장하는 것입니다 malloc 크기 및 결과 메모리 범위와 함께 각 요청을 기록하는 자신의 기능을 사용하면 릴리스 빌드에서 '실제'로 다시 전환 할 수 있습니다. malloc.

다른 팁

디버깅을 위한 천박한 폭력을 신경쓰지 않는다면 #define 매크로를 사용하여 malloc에 ​​대한 호출을 연결하고 해제하고 처음 4바이트를 크기로 채울 수 있습니다.

의 곡에 맞춰

void *malloc_hook(size_t size) {
    size += sizeof (size_t);
    void *ptr = malloc(size);
    *(size_t *) ptr = size;
    return ((size_t *) ptr) + 1;
}

void free_hook (void *ptr) {
    ptr = (void *) (((size_t *) ptr) - 1);
    free(ptr);
}

size_t report_size(ptr) {
    return * (((size_t *) ptr) - 1);
}

그 다음에

#define malloc(x) malloc_hook(x)

등등

C 런타임 라이브러리는 그러한 기능을 제공하지 않습니다. 또한, 의도적으로 예외를 유발한다고해서 블록이 얼마나 큰지 알려주지 않습니다.

일반적 으로이 문제가 C에서 해결되는 방식은 할당 된 블록의 크기를 추적하는 별도의 변수를 유지하는 것입니다. 물론 이것은 때때로 불편하지만 일반적으로 다른 방법은 없습니다.

C 런타임 라이브러리 5월 할당 된 블록을 쿼리 할 수있는 힙 디버그 기능을 제공하십시오 (결국, free() 블록이 얼마나 큰지 알아야하지만 이런 종류의 일은 포트할 수 없을 것입니다.

와 함께 gcc 그리고 GNU linker, 당신은 쉽게 포장 할 수 있습니다 malloc

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


void* __real_malloc(size_t sz);
void* __wrap_malloc(size_t sz)
{
    void *ptr;

    ptr = __real_malloc(sz);
    fprintf(stderr, "malloc of size %d yields pointer %p\n", sz, ptr);

    /* if you wish to save the pointer and the size to a data structure, 
       then remember to add wrap code for calloc, realloc and free */

    return ptr;
}

int main()
{
    char *x;
    x = malloc(103);

    return 0;
}

그리고 컴파일합니다

gcc a.c -o a -Wall -Werror -Wl,--wrap=malloc

(물론 이것은 또한 G ++로 컴파일 된 C ++ 코드와 새로운 연산자 (원조 이름을 통해)와 함께 작동합니다.)

사실상, 정적/동적으로로드 된 라이브러리도 귀하의 __wrap_malloc.

아니요, 구현의 문서에있는 한 경계를 초과 할 때 예외에 의존 할 수 없습니다. 그것은 당신이 프로그램을 작성하기 위해 실제로 알 필요가없는 것들의 일부입니다. 실제로 알고 싶다면 컴파일러의 문서 또는 소스 코드를 파헤칩니다.

이를 수행 할 표준 C 기능이 없습니다. 플랫폼에 따라 포트할 수없는 방법이있을 수 있습니다. 어떤 OS 및 C 라이브러리를 사용하고 있습니까?

예외를 유발하는 것은 신뢰할 수 없음 - 청크 직후의 다른 할당이있을 수 있으므로 현재 청크의 한계를 초과 한 후까지는 예외를 얻지 못할 수 있습니다.

메모리 검사기가 좋아요 Valgrind 's Memcheck 그리고 Google의 TCMalloc (힙 체커 부품) 이런 종류의 것을 추적하십시오.

tcmalloc을 사용하여 물건이 할당 된 위치를 보여주는 힙 프로파일을 버릴 수 있습니다. sameheap ().

부분 솔루션 : Windows에서는 사용할 수 있습니다 PageHeap 할당 된 블록 외부에서 메모리 액세스를 포착합니다.

PageHeap은 Windows 커널에 존재하는 대체 메모리 관리자입니다 (NT 품종에서는 다른 버전을 사용하지 않아야합니다). 프로세스에서 모든 할당이 필요하고 메모리 페이지의 끝과 끝이 정렬 된 메모리 블록을 리턴 한 다음 다음 페이지를 접근 할 수 없게 만듭니다 (읽기 없음, 쓰기 액세스 없음). 프로그램이 블록의 끝을지나 읽거나 쓰려는 경우, 좋아하는 디버거로 잡을 수있는 액세스 위반을 얻을 수 있습니다.

얻는 방법 : Microsoft의 Windows 용 패키지 디버깅 도구를 다운로드하여 설치합니다. http://www.microsoft.com/whdc/devtools/debugging/default.mspx

그런 다음 gflags 유틸리티를 시작하고 세 번째 탭으로 이동하여 실행 파일의 이름을 입력 한 다음 키를 누릅니다. PageHeap Checkbox를 확인하고 확인을 클릭하면 좋습니다.

마지막 일 : 디버깅을 마치면 GFLAGS를 다시 시작하는 것을 잊지 말고 응용 프로그램의 PageHeap을 비활성화하는 것을 잊지 마십시오. gflags는이 설정을 레지스트리 (HKLM Software Microsoft Windows NT CurrentVersion Image File Execution Options )에 들어갑니다. 따라서 재부팅 전체에도 지속됩니다.

또한 PageHeap을 사용하면 응용 프로그램의 메모리 요구가 엄청나게 증가 할 수 있습니다.

당신이 원하는 일을하는 방법은 BE 할당 자. 모든 요청을 필터링 한 다음 디버깅 목적으로 기록하면 메모리가 자유롭게있을 때 원하는 것을 찾을 수 있습니다.

또한 프로그램의 끝에서 확인하여 할당 된 모든 블록이 해제되었는지 확인하고 그렇지 않은 경우 나열 할 수 있습니다. 이런 종류의 야심 찬 도서관도 취할 수도 있습니다 기능 그리고 매크로를 통한 파라미터는 메모리가 누출되는 위치를 정확히 알려줍니다.

마지막으로 Microsoft의 MSVCRT는 디버그 버전에서 메모리 문제를 찾기 위해 사용할 수있는 유용한 도구가 많이있는 AA 디버그 가능 힙을 제공합니다. http://msdn.microsoft.com/en-us/library/bebs9zyz.aspx

Linux에서는 Valgrind를 사용하여 많은 오류를 찾을 수 있습니다. http://valgrind.org/

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top