2017-11-25 2 views
0

다음 코드를 고려한다.동적 메모리 할당은 어떻게 작동합니까?</p> <pre><code>int *p = malloc(4); int *i = malloc(4); </code></pre> <p>이제 메모리 청크 (상기 상황에서 4 바이트)가 할당 된 상기 기본 주소는 <code>p</code>에 저장되어

라인에 메모리를 할당하는 중 int *i = malloc(4).

이 메모리 덩어리가 할당되었음을 컴파일러가 어떻게 알 수 있습니까?

int *p = malloc(4)으로 할당 된 동일한 메모리 덩어리를 할당하지 않는 이유는 무엇입니까?

+0

컴파일러는 알 필요가 없습니다. 실제로'free'에 대한 포인터를 전달할 수 있습니다. 유효하지 않은 포인터도 있습니다. 이는 [* undefined behavior *] (https://en.wikipedia.org/wiki/Undefined_behavior)로 이어지지 만 C 컴파일러가이를 막을 수는 없습니다. –

+0

귀하의 C dev. – Stargateur

+0

편집하면 질문이 완전히 불분명 해집니다. 대담한 문장은 두 가지 다른 것을 말하고 의미가 없습니다. – dbush

답변

2

코드에서 malloc과 같은 루틴을 사용하고 코드를 컴파일하여 실행 프로그램에 연결하면 소프트웨어 루틴 라이브러리가 코드에 링크됩니다. 해당 라이브러리의 루틴에는 운영 체제에서 메모리를 요청하고, 해당 메모리를 부분으로 나누어 요청할 때 malloc으로주고, 제공된 내용과 free으로 릴리스 된 내용을 추적하기위한 소프트웨어가 있습니다.

그래서 아주 작은 프로그램을 컴파일 할 때마다 사람들이 수년 동안 함께해온 추가 소프트웨어의 큰 라이브러리를 얻게됩니다.

+0

Ok ... 당신은 커널이 malloc에 ​​주어진 모든 메모리를 추적한다고 말합니다. ?????? –

+1

@Comp_sci_student : C의 구현에는 일반적으로 표준 C 라이브러리라고하는 소프트웨어 라이브러리가 제공됩니다. 이 라이브러리는 프로그램의 일부가됩니다. 동일한 프로세스를 사용하여 동일한 메모리를 사용하며, 직접 작성한 서브 루틴과 같습니다. 이 라이브러리의 소프트웨어는'malloc'과'free'에 대한 메모리를 추적합니다. 이 소프트웨어는 사용자 프로세스 외부의 운영 체제에서 메모리를 요청합니다. 운영 체제에는 프로세스에 제공 한 메모리를 추적하는 자체 소프트웨어가 있습니다. –

+1

@Comp_sci_student : "kernel"이라는 단어가 다소 모호합니다.오늘날의 운영 체제는 거대하며 많은 레이어와 하위 시스템을 갖추고 있습니다. 커널이라고 부르는 부분은 그 중 일부 또는 대부분 일 수 있으며 일반적으로 메모리 관리는 어느 정도까지 그 부분입니다. –

1

컴파일러는 누가 메모리를 가지고 있고 이전에 할당 된 메모리를 우연히 짓밟는 지 알기위한 책임이 없습니다. 이것은 운영 체제의 일입니다. 컴파일러는 어셈블리 코드에서 적절한 시스템 호출을 만들어 OS에서 동적 메모리에 대한 포인터를 가져 오는 어셈블리 코드를 생성합니다. 설명하기 위해 여기에 바보 같은 예입니다 :

0x0000000100000f50 <+0>:  push %rbp 
    0x0000000100000f51 <+1>:  mov %rsp,%rbp 
    0x0000000100000f54 <+4>:  sub $0x10,%rsp 
    0x0000000100000f58 <+8>:  mov $0x4,%eax 
    0x0000000100000f5d <+13>: mov %eax,%edi 
    0x0000000100000f5f <+15>: movl $0x0,-0x4(%rbp) 
    0x0000000100000f66 <+22>: callq 0x100000f8a 
    0x0000000100000f6b <+27>: mov %rax,-0x10(%rbp) 
    0x0000000100000f6f <+31>: mov -0x10(%rbp),%rax 
    0x0000000100000f73 <+35>: mov %rax,%rdi 
    0x0000000100000f76 <+38>: callq 0x100000f84 
    0x0000000100000f7b <+43>: xor %eax,%eax 
    0x0000000100000f7d <+45>: add $0x10,%rsp 
    0x0000000100000f81 <+49>: pop %rbp 
    0x0000000100000f82 <+50>: retq 

을 주목 callq 라인 :이 프로그램을 컴파일하고 main이 분해 될 때

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

int main(void) { 
    int* ptr = malloc(4); 
    free(ptr); 
    return 0; 
} 

지금, 어셈블리 코드가 같이 보입니다. 컴파일러는 적절한 시스템 호출을 호출하여 동적 메모리를 확보합니다.

+0

이들은 시스템 호출이 아니라 라이브러리 루틴 호출입니다. 라이브러리 루틴은 시스템 호출을 포함하지만 메모리를 관리하기위한 상당한 인 프로세스 (in-process) 소프트웨어도 포함합니다. 모든 할당에 대해 시스템 호출을 사용하는 것은 비효율적입니다. 라이브러리는 시스템에서 많은 양을 요구하고 필요에 따라 조각으로 분할합니다. –

+0

@EricPostpischil 맞습니다. 실제 sys 호출을 포함하는 라이브러리 함수로의 점프를 지정해야합니다. – Miket25

관련 문제