2012-01-10 3 views
-1

이 여기에 코드의 사용 변경 :포인터 주소는 malloc에 ​​

void main() { 
    int i,*s; 
    for(i=1;i<=4;i++) { 
     s=malloc(sizeof(int)); 
     printf("%lu \n",(unsigned long)s); 
    } 
} 

내 빌려 INT의 크기는 2 바이트, 그래서해야하지 16 비트에 의해 증분의 printf 명령 인쇄 주소는, 대신에이 주소를 인쇄 다음과 같이 :

2215224120 
2215224128 
2215224136... 

왜 이렇게할까요?

+0

'malloc'은 주소 공간 전체에 주소를 반환 할 수 있습니다. – Mat

+0

프로세서 아키텍처는 무엇입니까? 'malloc'은 누구를 사용하고 있습니까? –

+0

@Mat이 말했듯이, malloc에 ​​의해 반환 된 주소에 대해서는 어떤 가정도 할 수 없습니다. 일반적으로 최소 정렬과 최소 크기 할당이 8 바이트 인 것처럼 보입니다. –

답변

1

malloc()은 이러한 보증을 제공하지 않습니다. 자체 메모리 관리 결정에 따라 일부 메모리를 할당하고 그에 대한 포인터를 반환합니다. 사실, 많은 구현은 메모리 관리 메타 데이터에 대해 포인터가 반환되기 바로 전에 여분의 메모리를 사용합니다.

0

귀하는 주소 malloc의 패턴에 관해 어떠한 보증도하지 않습니다.

+0

특정 플랫폼 –

2

호출 된 정렬입니다. 대부분의 CPU는 일부 경계에서 메모리를 정렬해야하며 일반적으로 4 또는 8로 정렬해야합니다. 주소를 잘못 정렬하면 segfault 또는 bus 오류가 발생합니다.

5

관리되는 메모리는 운영 체제에 따라 다릅니다. 그것은 모든 곳에서 메모리를 할당 할 수 있습니다, 당신은 절대적으로 메모리가 어디로 될지에 대한 가정을 할 수 없습니다.

대부분의 메모리 할당 자도 약간의 오버 헤드가 있으므로 간단한 2 바이트 할당이라도 8 바이트 이상을 차지할 수 있습니다. 게다가 주소는 여러 가지 이유 (예 : 성능과 정렬되지 않은 주소에서 읽을 때 일부 CPU가 충돌하기 때문에)에 정렬되어야 할 수도 있습니다.

결론 - malloc의 반환 값을 그대로 사용하면서 추측이나 가정을하지 마십시오.

+1

+1에 대한 최소 정렬을 제외하고는 보증이 없으며 부기 및 정렬 오버 헤드가 보통 두 배 이상 증가하기 때문에 4 바이트 또는 8 바이트 블록 할당을 권장하지 않습니다. –

+0

물론입니다. 물론 미니 할당을 위해 고안된 자신의 수퍼 특수 할당자를 작성하지 않는 한. 그러나 정상적인 삶에서 작은 할당은 여러 가지 이유로 나쁜 것입니다. – EboMike

+0

도움을 주셔서 감사합니다 – Akash

1

malloc()은 기본 하드웨어, OS, 드라이버 등을 추상화합니다. 메모리 할당 패턴은 다양한 매개 변수로 인해 시스템마다 다를 수 있습니다.

그러나 다음은 항상 옳다 대한 malloc()

  1. malloc() 기능 size 바이트를 할당하고 할당 된 메모리에 대한 포인터를 반환 유지 몇 가지 있습니다.
  2. 메모리가 초기화되지 않았습니다.
  3. size이 0이면 malloc()NULL 또는 나중에 free()으로 성공적으로 전달 될 수있는 고유 한 포인터 값을 반환합니다.
  4. malloc()은 모든 종류의 변수에 맞게 적절하게 정렬 된 할당 된 메모리에 대한 포인터를 반환합니다. 오류가 발생하면 NULL을 반환합니다.
  5. NULL 또한 보조 노트에 zero

의 크기 malloc()에 성공적으로 호출에 의해 반환 될 수 있습니다 , 다음과 같이 내가 프로그램을 수정

포인터

를 인쇄 %p 형식 지정자를 사용할 수 있습니다

#include <stdlib.h> 

int main(void) { 
    int i,*s; 
    printf("sizeof(int) = %zu \n", sizeof(int)); 

    for(i=1;i<=4;i++) { 
     if ((s=malloc(sizeof(int))) == NULL) { 
      printf("unable to allocate memory \n"); 
      return -1; 
     } 
     printf("%p \n",s); 
    } 

    return 0; 
} 

출력은 다음과 같다 :

$ ./a.out 
sizeof(int) = 4 
0x9d5a008 
0x9d5a018 
0x9d5a028 
0x9d5a038 
$ 
+0

* malloc()은 모든 종류의 변수에 맞게 적절하게 정렬 된 할당 된 메모리에 대한 포인터를 반환합니다. * SSE는 16 바이트 정렬이 필요하지만 Win32/Linux malloc은 일반적으로 8 비트이므로 Windows 및 Linux의 경우에는 그렇지 않습니다. 바이트 정렬. –

+0

@PaulR 좋은 지적입니다! 감사! –

+0

-1 malloc의 결과를 C로 형변환하기 위해, 절대해서는 안됩니다. [C FAQ] (http://c-faq.com/malloc/mallocnocast.html). – Lundin