内存管理

2023/7/20 c

# malloc 函数

1.malloc 函数的功能是在内存中动态地分配一块 size 大小的内存空间。

2.使用 malloc 函数,要包含 stdlib.h 头文件。

3.malloc 函数会返回一个指针,指向分配的内存空间。如果分配出现错误,则返回 NULL

4.使用 malloc 函数分配的内存空间位于堆中,而不是栈中

5.使用完这块内存之后,一定要将其释放掉,释放内存空间使用的是 free 函数。

# 示例一

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

int main() {
    int *p;
    p = (int*) malloc(sizeof(int));
    *p = 1000;

    printf("%d",*p); // 1000

    // 释放内存
    free(p);
    return 0;
}

# 示例二

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

int main() {
    int *numbers;
    numbers = malloc(5 * sizeof(int));

    numbers[0] = 1;
    numbers[1] = 5;

    // int 类型指针每次移动4个字节
    printf("%p\n",&numbers[0]);  // 0000023dfa661450
    printf("%p\n",&numbers[1]);  // 0000023dfa661454

    printf("%d\n",*numbers);     // 1
    printf("%d\n",*(numbers+1)); // 5

    // 释放内存
    free(numbers);
    return 0;
}

# calloc 函数

1.calloc 函数的功能是在内存中动态分配 n 个长度为 size 的连续内存空间

2.使用 calloc 函数,也要包含头文件 stdlib.h。

3.calloc 函数会返回一个指针,该指针指向动态分配的连续内存空间的首地址。

4.当空间分配错误时,返回 NULL。

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

int main() {
    int *numbers;
    // void * calloc(unsigned n, unsigned size);
    numbers = (int *)calloc(5,sizeof(int));

    numbers[0] = 1;
    numbers[1] = 5;

    // int 类型指针每次移动4个字节
    printf("%p\n",&numbers[0]);  // 0000025e1a091450
    printf("%p\n",&numbers[1]);  // 0000025e1a091454

    printf("%d\n",*numbers);     // 1
    printf("%d\n",*(numbers+1)); // 5

    // 释放内存
    free(numbers);
    return 0;
}

# realloc 函数

1.realloc 函数的功能是重新分配内存空间,参数 ptr 是一个指针,指向一块已经分配了内存的空间,size 是重新分配的内存空间的大小。

void *realloc(void *ptr, size_t size);

2.size 表示新分配的内存空间的大小,其值可以是任意的,既可以比原来的数值大,也可以比原来的数值小。

3.返回值是一个指向新地址的指针,如果出现错误,则返回 NULL。

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

int main() {
    int *numbers;
    char * str;
    // 分配内存
    numbers = (int *)malloc(5*sizeof(int));
    numbers[0] = 99;
    printf("%d\n",numbers[0]); // 99

    // 重新分配内存
    str = realloc(numbers,sizeof (char )*5);

    str[0] = 'h';
    str[1] = 'e';
    str[2] = 'l';
    str[3] = 'l';
    str[4] = 'o';

    printf("%d\n",numbers[0]); // 1819043176 (内存被清除了)
    printf("%s\n",str);        // hello
    printf("%c\n",str[1]);     // e

    // 释放内存
    free(str);
    return 0;
}

# 内存泄露

使用 malloc 等函数分配过内存后,还需要使用 free 函数及时释放内存。如果不进行释放,就会造成内存泄漏,甚至会导致系统崩溃。

free 函数可以实时地执行回收内存操作。如果程序很简单,程序结束之前不会使用过多的内存,不会降低系统的性能,可以不用写 free 函数。程序结束后,操作系统会自动完成释放的功能。

# 内存丢失

由于 pOld 所指向的内存空间是原来 pNew 指向的,于是这块空间被释放了。但是 pOld 原来指向的那块内存空间还没有被释放(因为没有指针指向这块内存),这块内存就造成了丢失。

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

int main() {
    int *pOld,*pNem;

    pOld = (int*) malloc(sizeof(int));
    pNem = (int*) malloc(sizeof(int));

    pOld = pNem;

    // 因为pOld和pNew指向同一块内存空间,释放后会导致内存丢失
    // 而pNew没有指针指向这块内存,这块内存就丢失了
    free(pOld);
    return 0;
}