2013-08-03 2 views
-1
#include <stdio.h> 
#include <stdlib.h> 

int main(void) 
{  
    int *arr = (int*)malloc(10); 
    int i; 
    for(i=0;i<100;i++) 
    { 
    arr[i]=i; 
    printf("%d", arr[i]); 
    } 
    return 0; 
} 

위의 프로그램에서 malloc을 호출하면 10 바이트의 메모리가 할당되고 각 int 변수는 2 바이트를 차지하므로 각각 2 바이트의 int 변수 5 개를 저장할 수 있습니다. 따라서 동적으로 할당 한 총 10 바이트를 구성합니다.malloc 비 결정적 동작

하지만 for-loop를 호출하면 99 번째 색인까지 값을 입력하고이 값들을 모두 저장할 수있게되었습니다. 그래서 나는 100 개의 int 값을 저장한다면 그것은 단지 200 바이트의 메모리를 의미하지만 10 바이트 만 할당 할 수 있습니다.

그래서이 코드의 결함은 무엇입니까? 또는 malloc은 어떻게 작동합니까? 그런 식으로 malloc의 동작이 비 결정적이라면 적절한 동적 메모리 처리를 어떻게 달성 할 수 있습니까?

+0

그러나 malloc (10)은 동적이 아닙니다. Malloc (N * sizeof (int))은 동적입니다. 10이 항상 10 인 경우 int arr [10]을 사용할 수 있습니다. –

+0

... (거의 의미가없는) 메모리 누출을 피하십시오. – WhozCraig

+0

아무에게도 malloc 반환 값을 전송하지 말라고 말한 적이 없습니까? – Jens

답변

1

어리석은 행동을하면 어리석은 행동이 예상됩니다.

그러한 말은 일반적으로 OS가 운영 체제 (페이지 같은)가 선호하는 메모리 덩어리를 요구하고 그 메모리를 관리하도록 구현됩니다. 이것은 특히 작은 크기의 malloc을 많이 사용하는 경우 미래의 malloc 속도를 높입니다. 그것은 상당히 비싼 컨텍스트 스위치의 수를 줄입니다.

+0

큰 배열/할당을 사용하여 많은 소규모 할당보다 적절한 위치 계산을 수행하고 있습니까? 'malloc'은 단일 1GB 위치가 완전히 연속 된 주소 공간이라는 것을 보장 할 수 있습니까? –

+0

각 malloc은 지정된 크기 (또는 NULL)의 연속 메모리를 반환합니다. –

+0

@huseyintugrulbuyukisik Per C9899 7.22.3.4,'malloc()'* "malloc 함수는 크기가 size이고 값이 불확정 인 객체를위한 공간을 할당합니다."* 연속적인 것은 보는 사람의 시야에 있지만 멀리있는 당신이 염려 하듯이, 네, ** malloc()에 대한 ** ** ** 호출에서 온 것이라면 연속적입니다. – WhozCraig

0

malloc은 정확히 n 바이트 메모리를 할당합니다. 코드가 PC에서 실행될 수 있지만 할당되지 않은 메모리에서 작동하는 것은 정의되지 않은 동작입니다.

작은 노트

...

지능은 서로 다른 아키텍처/SDK를에 변화, 2 바이트하지 않을 수 있습니다. n 개의 정수 요소에 메모리를 할당하려면 malloc(n * sizeof(int))을 사용해야합니다. 모든 짧은

, 당신은 언어가 제공하는 다른 도구 (sizeof, realloc, free 등) 동적 메모리를 관리.

+0

"당신은'arr [i * sizeof (int)] = i'를하지 말고'arr [i]'= i"가 아니라; 이것은 정확히 잘못된 것입니다. 첨자'i'는 타입에 관계없이'i'th * byte *가 아닌 배열의 i 번째 원소 *에 접근합니다. –

+0

예, arr은 int * 타입이므로 'i'만으로 충분합니다. 수정해 주셔서 감사합니다. –

0

우선, 대부분의 운영 체제에서 int의 크기는 4 바이트입니다. 다음과 같이 확인할 수 있습니다 : printf("the size of int is %d\n", sizeof(int)); malloc 함수를 호출하면 힙 메모리에 크기가 할당됩니다. 힙은 동적 할당을 위해 별도로 설정됩니다. 힙의 블록 할당 및 할당 해제에는 강제 패턴이 없습니다. 언제든지 블록을 할당하고 언제든지 해제 할 수 있습니다. 이렇게하면 힙의 어느 부분이 주어진 시간에 할당되거나 해제되는지를 추적하는 것이 훨씬 더 복잡해집니다. 프로그램이 작고 힙에 충돌이 없기 때문에이 값을 100 이상으로 실행하면이 값을 실행할 수 있습니다. malloc으로 무엇을하는지 알게되면 적절한 동적 메모리 처리를 사용하여 프로그램을 빌드합니다. 코드에 부적절한 malloc 할당이 있으면 프로그램의 동작이 "알 수 없음"입니다. 하지만 gdb 디버거를 사용하여 세분화가 표시되는 위치와 그 대상이 힙에있는 방식을 찾을 수 있습니다.

+0

형식 지정자가 실제 인수와 일치하지 않으므로 printf에 정의되지 않은 동작이 있습니다. 부호가있는 유형과 부호가없는 유형은 ** 교환 할 수 없습니다 **. C99는 size_t에 대한 형식 지정자도 도입했습니다. 당신이 그것을 보았습니다 :-) – Jens

+0

size_t는 부호없는 int로 –

+0

거의 것으로서'% zu'를 사용할 수 있습니다. '% zu'는 정확 합니다만, size_t는 * any * unsigned 타입이 될 수 있습니다. – Jens

2

결함은 예상대로입니다. 당신은 컴파일러에게 거짓말을했습니다. 실제로 100 * sizeof (int) 바이트를 썼을 때 "나는 단지 10 바이트 만 필요합니다". 할당 된 영역을 넘어 서면 정의되지 않은 동작이고 아무것도 발생하지 않을 것으로 예상되는 것에서부터 충돌이 예상되는 것에 이르기까지 어떤 일이 발생할 수 있습니다.

0

C는 배열 액세스에 대해 경계 검사를 수행하지 않습니다. 만약 당신이 10 요소의 배열을 정의하고 a[99]에 쓰기를 시도하면, 컴파일러는 당신을 멈추게 할 아무 것도하지 않을 것이다. 동작이 이고 정의되지 않음입니다. 즉, 컴파일러가 해당 상황에 대해 특별히 아무 것도 할 필요가 없음을 의미합니다.그것은 충돌하지 않을 것이라는 의미에서 "작동"할 수 있지만, 나중에 문제가 발생할 수있는 과 마찰을 빚어 왔습니다.

malloc을하고

바이트의 관점에서 생각 요소의 관점에서 생각하지 않습니다. N 정수에 공간을 할당하려면,

int *arr = malloc(N * sizeof *arr); 

으로 작성하고 컴파일러가 바이트 수를 계산하게하십시오.

관련 문제