C语言动态内存管理

目录

引言:

为什么进行动态内存管理

二、有关动态内存管理的库函数

2.1 malloc

2.2 calloc

2.3 ralloc

realloc可能会改变内存块的位置

2.4 free

三、有关动态内存管理容易出现的问题

3.1 对NULL指针进行解引用操作

3.2  对动态开辟空间的越界访问

3.3 对于非动态内存进行free

3.4  动态开辟内存忘记释放( 内存泄漏 )


C语言动态内存管理是指在程序运行时,根据需要动态地分配和释放内存空间。这种管理方式相比于静态内存管理具有更高的灵活性和效率。

引言:

为什么进行动态内存管理

C语言动态内存管理是指在程序运行时,根据需要动态地分配和释放内存空间。这种管理方式相比于静态内存管理具有更高的灵活性和效率。

  • 允许程序运行或停止时分配和释放内存。
  • 处理不确定大小的数据。
  • 提高程序的灵活性和可延展性。

二、有关动态内存管理的库函数

2.1 malloc

  • malloc(): 用于在堆区分配一块指定大小的内存空间。如果分配成功,它返回一个指向分配区域的指针;如果分配失败,则返回 NULL

函数原型:

void* malloc (size_t size);

按照malloc函数的特点我们可以检测函数内存是否开辟成功,通过检测返回指针类型:

int *ptr = (int *)malloc(sizeof(int));
if (ptr == NULL) {
    perror("malloc");
}

注意:

  • 在使用动态内存分配后,应该始终检查返回的指针是否为NULL或空指针,以确保内存分配成功。
  • 如果分配失败,应适当处理,释放掉已经分配的内存。

2.2 calloc

  • calloc(): 类似于 malloc(), 但它会将分配的内存空间初始化为。它接受两个参数:元素的数量和每个元素的大小

函数原型:

void* calloc (size_t num, size_t size);

运用calloc ( ) 时候,也是要进行返回值检测:

int *ptr = (int *)calloc(sizeof(int));
if (ptr == NULL) {
    perror("calloc");
}

2.3 ralloc

  • realloc(): 用于调整已分配内存块的大小。它接受两个参数:原有内存块的指针和新的大小。如果成功,它返回一个指向新内存块的指针;如果失败,它保留原有内存块并返回 NULL

函数原型:

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

同malloc()和calloc()一样,ralloc()也要进行返回值检测:

int* ptr1 = (int*)realloc(ptr,sizeof(int));
if (ptr1 == NULL){
    perror(realloc);
}
  • ptr是指向已分配内存块的指针.
  • size是新的内存块大小(以字节为单位)。
realloc可能会改变内存块的位置
  1. 当你尝试通过realloc来增大一个内存块的大小时,如果当前内存块后面有足够的连续空间,realloc会简单地扩大这块内存,并返回原来的指针。
  2. 如果当前内存块后面的空间不足以满足新的大小要求,realloc会在堆内存中寻找一个更大的连续空间,将原有数据复制到新的位置,然后释放原来的内存块,并返回新内存块的地址。

2.4 free

  • free():用于释放由malloc()分配的内存空间,接受一个指向要释放内存的指针作为参数.

函数原型:

void free (void* ptr);
  • 只有通过malloccalloc, 或 realloc等函数分配的内存空间才能被free释放。
  • 不能释放已经被释放过的内存,这将导致未定义行为,可能导致程序崩溃。
  • 释放内存后,不应继续使用该内存空间,否则可能导致未定义行为和潜在的错误。
  • 在程序结束前,应确保所有动态分配的内存空间都已被释放,以避免内存泄漏

应用:

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

int main() {
    int* ptr = (int*)malloc(sizeof(int)); // 动态分配内存
    if (ptr == NULL) {
        printf("内存分配失败\n");
        return 1;
    }
    *ptr = 42; // 使用动态分配的内存
    printf("动态分配的内存中的值:%d\n", *ptr);
    free(ptr); // 释放内存
    ptr = NULL;
    return 0;
}

三、有关动态内存管理容易出现的问题

3.1 对NULL指针进行解引用操作

void test()
{
 int *p = (int *)malloc(INT_MAX/4);
 *p = 20;//如果p的值是NULL,就会有问题
 free(p);
}

3.2  对动态开辟空间的越界访问

void test()
{
 int i = 0;
 int *p = (int *)malloc(10*sizeof(int));
 if(NULL == p)
 {
 exit(EXIT_FAILURE);
 }
 for(i=0; i<=10; i++)
 {
 *(p+i) = i;//当i是10的时候越界访问
 }
 free(p);
}

3.3 对于非动态内存进行free

void test()
{
 int i = 0;
 int *p = (int *)malloc(10*sizeof(int));
 if(NULL == p)
 {
 exit(EXIT_FAILURE);
 }
 for(i=0; i<=10; i++)
 {
 *(p+i) = i;//当i是10的时候越界访问
 }
 free(p);
}

3.4  动态开辟内存忘记释放( 内存泄漏 )

void test(void)
{
	int* p = (int*)malloc(sizeof(int));
	if (p == NULL){
		perror("malloc");
	}

}

int mian()
{
	test();
	return 0;
}

 

评论 15
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值