关于C语言中动态分配内存的4个函数

C语言中的动态分配内存

4个动态分配内存函数:mallocfreecallocrealloc,这些内存管理函数声明在在 stdlib.h头⽂件中

为什么要有动态内存分配?

程序运行时不确定需要多少内存空间。在编译期无法确定程序运行期间需要分配多大的内存块。此时就需要在运行时动态申请和释放内存

int x = 0;//在栈空间给变量分配4个字节
char ch = 'a';//在栈空间给变量分配1个字节
int arr[10] = {0};//在栈空间分配10个字节
// 但局限性很大  已经把空间写“死”
malloc
malloc(size_t size)
  1. 功能:分配指定大小的内存块,返回指向内存块的指针。
  2. 参数:size - 指定要分配的内存字节数。
  3. 返回值:如果分配成功,返回一个指向已分配内存的指针;如果分配失败,返回NULL
  4. 使用malloc分配的内存需要使用free函数释放,否则会造成内存泄漏。
  5. malloc分配的内存不会被初始化,内容是未定义的。
  6. 调用malloc分配指定大小的内存–检查返回值是否为NULL–使用分配到的内存–调用free释放内存
int *ptr = (int *)malloc(sizeof(int) * 10);
if (ptr == NULL) {
   perror("malloc");//打印错误信息
		return 1;
}
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr = (int *)malloc(sizeof(int));  // 申请一个整型变量的内存
    if (ptr == NULL) {
        printf("内存分配失败。\\n");
        return 1;
    }

    *ptr = 100;  // 给分配的内存赋值
    printf("分配的内存值为: %d\\n", *ptr);

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

free

是用于释放由动态内存分配函数(如malloccallocrealloc)分配的内存。free函数帮助管理内存使用,避免内存泄漏。

free函数的原型定义如下:

void free(void *ptr);
  • 释放正确:确保在不再需要内存时调用free函数,避免内存泄漏。
  • 释放顺序:如果多个内存块由同一个malloc调用分配,释放时应遵循相同的顺序。
  • 释放已释放内存:释放同一块内存多次会导致未定义行为。
  • 释放未分配内存:尝试释放未分配的内存会导致程序崩溃
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *p;
    p = (int *)malloc(sizeof(int)); // 分配内存
    if (p != NULL) {
        *p = 100; // 使用内存
        printf("Memory allocated at address: %p\\n", p);
        free(p); // 释放内存
        p = NULL; // 避免释放已释放内存
    }
    return 0;
}

calloc

calloc 函数也⽤来动态内存分配, calloc会给申请的每个字节初始化为0,而malloc不会初始化内存

代码原型

void *calloc(size_t num_elements, size_t size_of_element);
#include <stdio.h>
#include <stdlib.h>

int main() {
    int *ptr1, *ptr2;

    // 使用 malloc 分配内存
    ptr1 = (int *)malloc(10 * sizeof(int));
    if (ptr1 == NULL) {
        fprintf(stderr, "Memory allocation failed!\\n");
        return 1;
    }
    // 注意:这里需要手动初始化内存

    // 使用 calloc 分配内存
    ptr2 = (int *)calloc(10, sizeof(int));
    if (ptr2 == NULL) {
        fprintf(stderr, "Memory allocation failed!\\n");
        return 1;
    }
    // 注意:这里内存已经被初始化为0

    // 输出结果,ptr2 的内容应该是0
    for (int i = 0; i < 10; i++) {
        printf("%d ", ptr2[i]);
    }
    printf("\\n")
    // 释放内存
    free(ptr1);
    free(ptr2);
    return 0;
}

realloc

realloc函数用于重新分配内存块的大小。

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

这个函数接受两个参数:

  1. ptr:这是要调整大小的内存块的指针。这个内存块必须是之前通过malloc, calloc, realloc等函数分配的。
  2. size:这是新的内存块的大小。如果size比当前内存块的大小大,那么realloc会增加内存块的大小;如果size比当前内存块的大小小,那么realloc会减少内存块的大小。

函数返回一个新的指针,指向调整后大小的内存块。如果调整大小失败,函数会返回NULL

例如,假设我们有一个通过malloc分配的整型数组:

int *arr;
arr = (int *)malloc(10 * sizeof(int));

如果我们要增加数组的大小,可以使用realloc

arr = (int *)realloc(arr, 20 * sizeof(int));

如果我们要减小数组的大小,可以使用realloc

arr = (int *)realloc(arr, 5 * sizeof(int));

需要注意的是,realloc函数在调整内存块大小时可能会导致数据丢失。如果在调用realloc之前,内存块正在被使用,那么在调整大小后,数据的访问位置可能会改变。因此,在调用realloc之前,应该确保内存块没有被使用,或者在调用realloc后正确处理数据的访问位置。

此外,如果realloc失败,函数会返回NULL。此时,应该检查返回的指针是否为NULL,并相应地处理错误情况。

realloc在调整内存空间的两种情况:

1:原有空间之后没有⾜够多的空间时,扩展的⽅法是:在堆空间上另找⼀个合适⼤⼩的连续空间来使⽤,并且把数据拷贝过去,这样函数返回的是⼀个新的内存地址。

2:要扩展内存就直接原有内存之后直接追加空间,原来空间的数据不发⽣变化,返回的起始地址还是旧的起始地址。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

遗落-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值