C malloc & free 实际例子

本文探讨了C语言中如何正确管理动态分配的内存,包括创建和释放结构体成员的内存。通过对两个不同示例的对比分析,说明了内存泄漏的问题及解决方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

数据到底存在哪里?

test2.c

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

typedef struct data{
    char *name ;
    int age;
}student;

student *stu_create(char *name, int name_len,int age)
{
    student *stu = (student *)malloc(sizeof(student));
    stu->name = (char *)malloc(name_len);
    memcpy(stu->name, name, name_len);
    stu->age = age;
    return stu;
}

void stu_release(student *stu)
{
    //free(stu->name);
    //stu->name = NULL;
    free(stu);
}

int main()
{
    char *name = "abc";
    student *stu = stu_create(name, 3, 10);
    printf("%s %d\n",stu->name, stu->age);
    char *tmp = stu->name;
    stu_release(stu);
    stu = NULL;
    printf("%s\n",tmp);
    return 0;
}

上面的程序,
在create函数里面分配了stu->name的内存
但在release函数里面没有free stu->name,(我把它注释掉了)

运行结果为
这里写图片描述

使用 valgrind

valgrind --tool=memcheck --leak-check=yes --show-reachable=yes ./test2

最后会发现内存泄漏,有3个字节的内存空间并没有被释放调
这里写图片描述

当把, 下面两句加上后

free(stu->name);
stu->name = NULL;

运行如下,并且可以valgrind,没有内存泄漏
这里写图片描述


这里写图片描述

通过打印地址,可以看到在create函数中malloc内存后
stu->name 和 main函数里面的name 地址不一样,一个是堆,一个是栈上的。


还有一种方式

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

typedef struct data{
    char *name ;
    int age;
}student;

student *stu_create(char *name, int age)
{
    student *stu = (student *)malloc(sizeof(student));
    stu->name = name;
    stu->age = age;
    return stu;
}

void stu_release(student *stu)
{
    free(stu);
}

int main()
{
    char *name = "abc";
    printf("%x\n", name);
    student *stu = stu_create(name, 10);
    printf("%x %x\n",stu->name, stu->age);
    stu_release(stu);
    stu = NULL;
    return 0;
}

这里写图片描述
这样name stu->name都在栈上


这里写图片描述
stu->name在只读内存上(即 main函数中的char *name),所以修改会出错

这里写图片描述
stu->name分配了内存,对其修改没有任何问题

### C语言 `malloc` 函数的使用教程 #### 什么是 `malloc` `malloc` 是一种用于动态内存分配的标准库函数,在运行时为程序提供所需的存储空间。它属于 `&lt;stdlib.h&gt;` 头文件的一部分,返回指向已分配内存区域的指针[^1]。 #### 函数原型 以下是 `malloc` 的标准定义: ```c void* malloc(size_t size); ``` 参数说明如下: - **size**: 表示要分配的字节数。 - 返回值: 成功时返回一个指向新分配内存的指针;如果失败,则返回 `NULL`[^2]。 #### 示例代码 下面是一个简单的例子展示如何使用 `malloc` 来分配并释放一块大小为 100 字节的空间: ```c #include &lt;stdio.h&gt; #include &lt;stdlib.h&gt; int main() { char *p; p = NULL; // 初始化为空 p = (char *)malloc(100); // 动态申请 100 字节的字符数组 if (p != NULL) { // 检查是否成功分配 printf(&quot;Memory allocated successfully at address %p\n&quot;, (void*)p); // 可在此处操作该内存 free(p); // 释放内存 p = NULL; // 将指针置零以防止悬空指针 } else { printf(&quot;Not enough memory to allocate!\n&quot;); } return 0; } ``` 上述代码展示了基本流程:先尝试获取一段指定长度的数据区段,接着验证请求的结果,并最终清理不再使用的资源。 #### 常见错误分析 尽管 `malloc` 提供了极大的灵活性,但在实际应用过程中容易犯一些典型失误,主要包括但不限于以下几个方面: 1. **忘记初始化指针** 若未将变量设置成初始状态即调用了 `free()` 或者再次执行新的 `malloc()` 调用前没有将其重设回 `NULL` ,则可能导致不可预测的行为甚至崩溃。 2. **越界访问** 当超出所允许范围读写数据时会造成缓冲溢出漏洞等问题。 3. **双重释放(duplicate frees)** 对同一个地址重复解除绑定会引发严重的系统异常状况。 4. **泄漏(leaks of resources)** 如果未能及时归还临时占用的部分就会累积形成浪费现象。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值