Bootstrap

大话C语言:第28篇 内存分配与释放

1 malloc函数

函数说明:

#include <stdlib.h>

void *malloc(size_t size);
功能:在内存的动态存储区(堆区)中分配一块长度为size字节的连续区域,用来存放类型说明符指定的类型。
	分配的内存空间内容不确定。
参数:
	size:需要分配内存大小(单位:字节)
返回值:
    成功:分配空间的起始地址
    失败:NULL

代码示例:

#include <stdio.h>  
#include <stdlib.h>  
  
int main() {  
    // 使用 malloc() 分配内存来存储 5 个整数  
    int *array = (int *)malloc(5 * sizeof(int));  
      
    // 检查 malloc() 是否成功分配了内存  
    if (array == NULL) {  
        printf("内存分配失败\n");  
        return -1; // 返回非零值表示错误  
    }  
  
    // 初始化分配的内存中的整数  
    for (int i = 0; i < 5; i++) 
    {  
        array[i] = i + 1;  
    }  
  
    // 打印整数的值  
    printf("数组中各元素分别是:\n");  
    for (int i = 0; i < 5; i++) 
    {  
        printf("%d ", array[i]);  
    }  
    printf("\n");  
  
    // 释放分配的内存  
    free(array);  
  
    // 尝试访问已释放的内存可能会导致问题,所以不再使用 array 指针  
    // 将指针设置为 NULL 以避免悬挂指针 
    array = NULL;  
  
    return 0;  
}

2 calloc函数

函数说明:

#include <stdlib.h>

void *calloc(size_t num, size_t size);
功能:该函数与malloc()类似,但它还需要一个额外的参数来表示要分配的元素数量。它会返回一个指向已初始化为零的内存块的指针。
参数:
    num指定要分配的元素数量。
    size指定每个元素的大小。
返回值:
    成功:分配的内存块的指针
    失败:NULL

代码示例:

#include <stdio.h>  
#include <stdlib.h>  
  
int main() {  
    // 使用 calloc() 分配内存来存储 10 个整数,并初始化为 0  
    int *array = (int *)calloc(10, sizeof(int));  
      
    // 检查 calloc() 是否成功分配了内存  
    if (array == NULL) 
    {  
        printf("内存分配失败\n");  
        
        return -1; 
    }  
  
    // 给数组中的每个元素赋一个值  
    for (int i = 0; i < 10; i++) 
    {  
        array[i] = i * 2; 
    }  
  
    // 打印数组中的值  
    printf("数组各个元素值分别是:\n");  
    for (i = 0; i < 10; i++)
    {  
        printf("%d ", array[i]);  
    }  
    printf("\n");  
  
    // 释放分配的内存  
    free(array);  
  
    // 将指针设置为 NULL,避免悬挂指针  
    array = NULL;  
  
    return 0;  
}

3 realloc()函数

函数说明:

#include <stdlib.h>

void *realloc(void *ptr, size_t new_size);
功能:用于调整之前分配的内存块的大小。如果调整成功,它会返回指向新内存块的指针;如果失败,它会返回NULL。
参数:
    ptr:指向一个之前由malloc(), calloc(), 或 realloc() 函数分配的内存块的指针。如果 ptr 是 NULL,那么 realloc() 的行为就如同 malloc(),分配一块大小为 new_size 的新内存。
    new_size:重新分配的内存块的大小,以字节为单位。
返回值:
	如果内存重新分配成功,realloc() 返回指向新内存块的指针。这个指针可能与 ptr 相同(如果重新分配发生在原地),也可能不同(如果内存块移动了位置)。
	如果内存重新分配失败,realloc() 返回 NULL,并且原内存块 ptr 保持不变(不会被自动释放)。    

代码示例:

#include <stdio.h>  
#include <stdlib.h>  
  
int main() {  
    int *array = (int *)malloc(5 * sizeof(int));  
    if (array == NULL) {  
        perror("Memory allocation failed");  
        return 1;  
    }  
  
    // 初始化数组  
    for (int i = 0; i < 5; i++) {  
        array[i] = i;  
    }  
  
    // 打印原始数组  
    printf("Original array:\n");  
    for (int i = 0; i < 5; i++) {  
        printf("%d ", array[i]);  
    }  
    printf("\n");  
  
    // 尝试将数组大小增加到10  
    int *new_array = (int *)realloc(array, 10 * sizeof(int));  
    if (new_array == NULL) {  
        printf("内存重新分配失败\n");  
        
        // 释放原始内存  
        free(array); 
        
        return 1;  
    }  
  
    // 更新指针  
    array = new_array;  
  
    // 初始化新分配的内存部分  
    for (int i = 5; i < 10; i++) 
    {  
        array[i] = i;  
    }  
  
    // 打印新数组  
    printf("扩展后的数组:\n");  
    for (int i = 0; i < 10; i++) 
    {  
        printf("%d ", array[i]);  
    }  
    printf("\n");  
  
    // 释放内存  
    free(array); 
    
    // 将指针设置为 NULL,避免悬挂指针  
    array = NULL; 
  
    return 0;  
}

4 free函数

函数说明:

#include <stdlib.h>
void free(void *ptr);
功能:释放ptr所指向的一块内存空间,ptr是一个任意类型的指针变量,指向被释放区域的首地址。
	对同一内存空间多次释放会出错。
参数:
	ptr:需要释放空间的首地址,被释放区应是由malloc函数所分配的区域。
返回值:无

代码示例:

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

int main() {
    int n = 0;
    printf("请输入要申请数组的个数: ");
    scanf("%d", &n);

    // 堆区申请 n * sizeof(int) 空间,等价int arr[n]
    int *arr = (int *)malloc(n * sizeof(int));
    if (arr == NULL) 
    {
        printf("申请空间失败!\n");
        
        return -1;
    }

    for (int i = 0; i < n; i++)
    {
        // 给数组赋值
        arr[i] = i;
    }

    for (int i = 0; i < n; i++) 
    {
        // 输出数组每个元素的值
        printf("%d, ", *(arr+i));
    }
    
    // 释放堆区空间
    free(arr);
    
    // 将指针设置为 NULL,避免悬挂指针  
    array = NULL; 

    return 0;
}

悦读

道可道,非常道;名可名,非常名。 无名,天地之始,有名,万物之母。 故常无欲,以观其妙,常有欲,以观其徼。 此两者,同出而异名,同谓之玄,玄之又玄,众妙之门。

;