2012-05-05 3 views
4

포인터를 확보하는 것과 관련하여 이론적 인 질문이 있습니다.길이를 모른 채 포인터를 놓으십시오.

사람 (프로그램 자체 또는 OS)이 포인터와 길이를 추적해야한다고 생각합니다. 왜?

float* pointer1 = malloc(100 * sizeof(float)); 

예 : 여기에 플로트 포인터가 있습니다. 누군가 내 포인터 1 어레이의 길이를 말해 줄 수 있습니까? 런타임에 함수/메소드를 호출하여 포인터의 길이를 얻을 수있는 방법이 없습니까? 따라서 프로그램 (또는 OS)가 실행 시간에 그것의 실제 길이를 모른 채 포인터의 메모리 일부를 해제 할 수있는 방법 :

free(pointer1); 

프로그램이 포인터의 길이가 무료로 알았다면, 왜 우리는 그 정보를 얻을 수없고 길이를 추적하는 다른 방법을 사용할 수 없습니다. 예 :

struct floatArray 
{ 
    float* pointer; 
    int length; 
} 

그래서이 문제는 정말 궁금합니다. 나는 OS가 어떻게 포인터 길이에 신경 쓰는지 배우고 싶다.

감사합니다.

Sait.

+0

"포인터를 해제"같은 것은 없다. malloc에서 얻은 * 객체 *를 해제합니다.그 객체에 대한 포인터는 객체를 해제 할 목적으로 객체를 참조하는 방법이지만 포인터를 해제하지는 않습니다. 당신은 그 대상을 자유롭게하고 있습니다. –

+0

@R .. 네, 맞습니다. 나는 "포인터를 사용하여 메모리에 저장된 객체를 해제하십시오."라고 말해야했습니다. +1. – Sait

답변

3

을 libraries-. 여기에는 블록 크기 외에도 정보가 포함됩니다.

이것을 구현하는 일반적인 방법 중 하나는 사용자 프로그램이 블록을 참조하는 데 사용하는 메모리 주소 바로 아래의 메모리에 메타 데이터를 저장하는 것입니다. 따라서 malloc에 ​​대한 호출이 주소 p을 반환하고 메타 데이터에 n 바이트가 포함 된 경우 메타 데이터는 에서 p-1에 저장됩니다.

+0

그렇다면 포인터의 길이를 가져 오는 전역 함수가없는 이유는 무엇입니까? 같은 것 : int GetLength (void * pointer). 유용하지 않겠습니까? – Sait

+1

@ zagy 유용 할 것입니다. 그러나 C 디자이너는 그런 식으로 구현자를 제약하지 않기로 결정했습니다. 많은 구현에는 구현 특정 확장과 같은 기능이 포함됩니다. –

2

일반적으로 직접 OS가 아니므로 malloc() 구현 - OS에서 메모리 블록을 더 많이 차지하는 메모리 관리자입니다. 보통,이 정보는 링크 된리스트에 저장 될 것이지만이 정보가 실제로 저장되는 방법을 보려면 libc의 malloc()을 살펴 보는 것이 좋습니다.

으로는 구현이 서로 다른 컴파일러 사이 다르기 때문에 그것을 할 수있는 표준 방법은 존재하지 않습니다, 지적/표준 C는 메모리 관리자가 실제로 메모리의 각 할당 된 블록에 대한 메타 데이터를 유지 않습니다

+0

'malloc()'구현을 확인하는 것이 좋습니다. 감사. – Sait

1

OS가 요청한 정확한 길이를 추적하지는 않습니다. 종종 길이는 다양한 내부 사정으로 변경 (증가)되거나 액세스가 느린 방식으로 저장됩니다. 추가 정보가 인코딩되어있을 수 있습니다 (일반적으로 크기는 2의 제곱의 배수 및 플래그로 사용되는 하위 비트로 정렬됩니다). 일부 malloc 구현체 (특히 임베디드 구현체)는 free()을 전혀 구현하지 않으며이 정보를 저장할 필요가 없습니다.

C 언어 설계자는 C 라이브러리 구현에 이러한 종류의 자유를 허용하려고했기 때문에 프로그램에서 malloc 된 버퍼의 크기를 검색 할 수 없습니다.

+0

아무도 사용 된 메모리 공간을 추적하지 못하면 어떻게 누군가에게 빈 메모리 공간을 제공 할 수 있습니까? 그것은 나에게 이해가되지 않는다. 우리가 사용하는 플랫폼은이 경우 더 불안정해야했습니다. – Sait

+0

@ zagy, 아니요, 부팅 할 때 빈 힙을 설정하고 시작 포인터를 설정 한 다음 누군가 mallocs가 추가되면 추가 할 수 있습니다. 결국 메모리가 부족하여 재부팅해야합니다. 일반적으로 부트시 malloc이 여러 개있는 임베디드 시스템에서만이 사실을 볼 수 있습니다. 그러면 다시 malloc되지 않습니다. Linux 커널 디 컴프레서도 이것을 수행합니다. 일단 실제 커널을 압축 해제하면 힙이 완전히 지워집니다. – bdonlan

1

는 MSVC 또는는 MinGW 사용하면 (표준이 아닌!)를 사용할 수있는 기능 _msize

float* pointer1 = malloc(100 * sizeof(float)); 
printf("%lu bytes with %lu elements", (unsigned long)_msize(pointer1),(unsigned long)_msize(pointer1)/sizeof*pointer1); 
+0

흥미 롭습니다 ... 나는 그런 기능이 있다는 것을 정말로 몰랐습니다. 감사. 그리고 그것이 비표준이라는 것을 듣고 슬프다. – Sait

관련 문제