동적 메모리 할당C 언어

6869 단어

논리적 파티션

  • 창고
  • 퇴적지
  • 정적 영역
  • 상량구
  • 코드 영역
  • 코드 구역, 상수 구역, 정적 구역, 퇴적 구역, 창고 구역 이 배열 순서는 주소에 따라 작은 것에서 큰 것으로 배열된다

    코드 영역:


    읽기 전용이었어
    프로그래머는 그것을 조작할 필요가 없다. 안에 코드를 컴파일한 후 형성된 이진법이 놓여 있다

    상수 영역:


    읽기 전용이었어
    예를 들어 "acfun", "Q", 5 등등의 상수는 상수 구역에 놓는다
    char *p ="bilibili";
    

    상수 영역의 내용을 수정하려는 모든 동작은 메모리 붕괴를 초래할 수 있습니다
    char arr[] ="bilibili";
    arr[0] = 'I';
    

    바늘로 문자열을 조작할 때 메모리 구역의 문제를 반드시 주의해야 한다
    strcpy(p, "123");
    p[0] = 'I';
    printf("%p
    ",p);

    정적 영역:


    static 키워드로 장식된 변수는 정적 구역에 놓고 정적 구역에 놓은 변수는 한 번만 초기화됩니다
    static int a = 10;
    
  • 초기 값을 주지 않으면 기본값은 0
  • 에 해당합니다.
    static int b;//      b = 0;
    
  • static로 수식된 정적 변수의 생명주기는 전체 프로그램의 생명주기와 같다. 즉, 프로그램이 종료된 후에야 방출된다(iOS 프로그래밍이 단일 클래스를 쓸 때static을 사용해야 한다)
  • int all = 10;//    ,         
    
    printf("%p
    ",&a);// , , , , printf("%p
    ",&all);// 0x7fff5fbff7b0 printf("%p
    ",&all);// 0x100001020

    스택:


    시스템에서 자동으로 할당 및 해제되는 연속 메모리로 프로그래머가 수동으로 관리할 필요가 없으며 크기도 1M-2M
    그는 자신이 관리하는 규칙이 있다. 창고 구역 메모리의 분배는 선진적인 후출의 원칙에 따른다
    int a = 10;//     a
    int b = 20;//     b
    
    printf("%p
    ",&a);// printf("%p
    ",&b);//

    이전에 배운 코드는 사실 모두 창고 구역에 놓았지만, 창고 구역이 넘치는 문제가 나타나지 않았다

    퇴적 구역:


    메모리가 비교적 큰 공간은 모두 퇴적 구역에 점용되고 있다. 퇴적 구역은 연속되지 않는 메모리 공간이기 때문에 우리 프로그래머가 수동으로 메모리를 분배하고 방출해야 한다.
    포인터 정의
    int *p =malloc(4);
    

    malloc는 프로그래머가 수동으로 메모리 공간을 분배하는 함수입니다. 함수의 매개 변수는 우리가 필요로 하는 메모리 공간을 놓습니다. 이 공간은 메모리를 쌓는 공간입니다.
    printf("%p
    ",p);// printf("%d
    ",*p);//

    방출 공간
    free(p);
    p = NULL;// p    0x0.
    

    연습


    세 단어를 메모리에 저장하고 출력하기
       char *word[3] = {0};//    
       char temp1[100] = {0};//         
       printf("       :
    "); for(int i = 0; i < 3; i++) { scanf("%s",temp1); word[i] =malloc(sizeof(temp1));// strcpy(word[i], temp1); } printf("**********************
    "); for(int i = 0; i < 3; i++) { printf("%s
    ",word[i]); free(word[i]);// , , word[i] =NULL; }

    메모리 할당 함수


    malloc와free... 이 함수들은 사용 가능한 메모리 탱크를 유지하고 프로그램에 메모리를 가리키는 바늘을 되돌려줍니다.이 메모리는 현재 어떤 방식으로도 초기화되지 않았다.만약 이 메모리가 매우 중요하다면 수동으로 초기화하거나calloc 함수를 사용할 수 있습니다.

    malloc 함수


    함수 원형

    void *malloc(size_t size);
    
  • size는 분배해야 하는 메모리 바이트(문자) 수입니다.만약 메모리 탱크의 메모리가 이 요구를 충족시킬 수 있다면,malloc는 분배된 메모리의 시작 위치를 가리키는 바늘을 되돌려줍니다.
  • malloc가 분배한 것은 연속적인 메모리이다.
  • 메모리 탱크가 비어 있으면malloc 함수는 운영체제에 요청합니다.만약 운영체제가malloc에 더 많은 메모리를 제공할 수 없다면malloc는NULL 포인터를 되돌려줍니다.따라서malloc가 되돌아오는 바늘을 검사하여 NULL이 아닌 것을 확보해야 한다
  • malloc는void*의 바늘을 되돌려줍니다.표준void * 포인터는 다른 모든 종류의 포인터로 변환할 수 있습니다.단, 일부 (구식) 컴파일러는 변환할 때 강제 형식 변환을 사용해야 할 수도 있습니다
  • 경계 정렬을 요구하는 기계에 대해malloc가 되돌아오는 메모리의 시작 위치는 경계 정렬에 대한 가장 엄격한 유형의 요구를 시종 만족시킬 수 있다.
  • char *p1 =malloc(4);
    for(int i = 0; i < 4; i++) {
        *(p1+i) = 65 + i;
        printf("%c
    ",*(p1+i)); } free(p1); p1 =NULL;

    free 함수


    함수 원형

    void free(void *pointer);
    
  • free의 매개 변수는 NULL이거나 이전에malloc,calloc 또는realloc에서 되돌아온 값입니다.
  • free에 NULL 파라미터를 전달하면 아무런 효과가 없음
  • calloc 함수


    함수 원형

    void *calloc(size_t num_elements,size_t element_size);
    
  • calloc도 메모리를 분배하는 데 사용된다.malloc와calloc 사이의 주요 차이점은 후자가 메모리를 가리키는 바늘로 되돌아오기 전에 그것을 0으로 초기화하는 것이다.하지만 효율이 낮아 보인다.
  • malloc와calloc는 메모리 수량을 요청하는 방식이 다르다.calloc의 매개 변수는 필요한 요소의 수량과 각 요소의 바이트 수를 포함합니다.이 값들에 따라 모두 분배해야 할 메모리를 계산해 낼 수 있다.
  • char *p2 =calloc(3, 1);           ,              
    
    for(int i = 0; i < 3; i++) {
        *(p2+i) = 'a';
        printf("%c
    ",*(p2+i)); } free(p2); p2 =NULL;

    연습하다


    calloc 함수를 사용하여 10개의 4바이트 공간을 분배하고 10개의 무작위 수치 범위를 10-30 사이에 저장한 다음 인쇄합니다
    char *p3 =calloc(10, 4);
    
    for(inti = 0; i < 10; i++) {
        *(p3+i) =arc4random()%21 + 10;
        printf("%d
    ",*(p3+i)); } free(p3);

    realloc 함수


    함수 원형

    void realloc(void *ptr,size_t new_size);
    
  • realloc 함수는 원래 분배된 메모리 블록의 크기를 수정하는 데 사용됩니다.이 함수는 메모리를 확대하거나 축소시킬 수 있다.
  • 만약에 확대된다면 이 메모리의 원래 내용은 여전히 보존되고 새로 증가한 메모리는 원래 메모리 블록의 뒤에 추가되며 새 메모리는 어떠한 방법으로도 초기화되지 않는다.
  • 만약 축소된다면 이 메모리 블록의 끝부분의 메모리는 제거되고 나머지 부분의 메모리의 원래 내용은 여전히 보존된다.
  • 원래의 메모리 블록이 크기를 바꿀 수 없으면realloc는 다른 정확한 크기의 메모리를 분배하고 원래의 메모리 내용을 새 블록에 복사합니다.따라서, Realloc를 사용한 후, 오래된 메모리를 가리키는 바늘을 사용할 수 없고, Realloc가 되돌아오는 새 바늘로 바꿔야 합니다.
  • realloc 함수의 첫 번째 인자가 NULL이면 그 행동은malloc와 똑같습니다.
  • int *p4 =malloc(4);
    int *p5 =realloc(p4, 8); p4     8      
      
    *p5 = 10;
    *(p5+1) = 20;
    
    *p4 = 11;
    *(p4+1) = 21;
      
    printf("%d
    %d
    ",*p5,*(p5+1)); printf("%d
    %d
    ",*p4,*(p4+1));

    memset 메모리 설정 함수

    int *p6 =malloc(4);
    

    여기에 정형을 성명한 것을 주의해라
    memset(p6, 65, 16);첫 번째 파라미터는 조작할 바늘을 놓고, 두 번째 파라미터는 내용(정형 또는 문자형)을 놓고, 세 번째 파라미터는 바이트를 놓는다.
    for(inti = 0; i < 4; i++) {
    printf("%c
    ",*(p6+i)); }

    memcpy 메모리 내용 복사 함수

    char*p7 =malloc(4);
    
    memcpy(p7, p6, 5);
     
    for(inti = 0; i < 4; i++) {
    //        *(p7 + i) = 66;
    printf("%c
    ",*(p7+i)); }

    메모리 비교 함수


    문자열 비교 함수와 같이 안의 내용을 비교하고 첫 번째 같지 않은 문자를 찾으면 ascii 부호표 값에 따라 차이가 난다
    int count =memcmp(p7, p6, 5);
    printf("%d
    ",count);

    동적 메모리 할당

    int *pi;
    pi = malloc(100);
    if(pi == NULL){
        printf("Out of memory!
    "); exit(1); }

    만약 메모리를 분배하는 데 성공한다면, 우리는 100바이트를 가리키는 바늘을 가지게 될 것이다.정형이 4바이트인 기계에서, 이 메모리는 25개의 정형 수조 원소의 수조로 간주될 것이다. 왜냐하면 pi는 정형을 가리키는 지침이기 때문이다.

    테크닉

    pi = malloc(25*sizeof(int));
    

    공통 동적 할당 오류


    오류가 발생하지 않는 메모리 분배기를 정의합니다

    #define malloc //                        maloc   。       ,         malloc,            。
    #define MALLOC(num,type) (type*)alloc((num)*sizeof(type))
    extern void *alloc(size_t size);
    
  • 메모리 할당 성공 여부를 확인하지 못했습니다
  • 액세스된 메모리는 다른 변수의 값을 저장할 수 있음
  • free에 전달되는 바늘은malloc,calloc 또는realloc 함수에서 되돌아오는 바늘이어야 합니다.
  • 좋은 웹페이지 즐겨찾기