C语言学习记录——사십팔 动态内存管理(3)

目录

一、常见的动态内存错误

1、对NULL指针的解引用操作

2、对动态开辟内存的越界访问

3、对非动态开辟空间使用free

4、使用free释放动态内存的一部分

5、对同一块动态内存多次释放

6、动态开辟内存忘记释放

二、练习

1、内存泄漏


一、常见的动态内存错误

1、对NULL指针的解引用操作

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

int main()
{
    int* p = (int*)malloc(40);
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        *(p + i) = i;
    }
    free(p);
    p = NULL;
    return 0;
}

如果malloc失败了,那么p就是空指针,对空指针进行解引用操作一定不行,所以要提前有判断。

2、对动态开辟内存的越界访问

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


int main()
{
    int* p = (int*)malloc(5 * sizeof(int));
    if (p == NULL)
    {
        return 0;
    }
    else
    {
        int i = 0;
        for (i = 0; i < 10; i++)
        {
            *(p + i) = i;
        }
    }
    free(p);
    p = NULL;
    return 0;
}

只开辟了5个整型的空间,但是要循环10个,所以造成了越界访问。

3、对非动态开辟空间使用free

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


int main()
{
    int a = 10;
    int* p = &a;
    *p = 20;
    free(p);
    p = NULL;
    return 0;
}

动态分配出现错误有时候会卡死。

4、使用free释放动态内存的一部分

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

int main()
{
    int* p = (int*)malloc(40);
    if (p == NULL)
    {
        return 0;
    }
    int i = 0;
    for (i = 0; i < 10; i++)
    {
        *p++ = i;
    }
    free(p);
    p = NULL;
    return 0;
}

当p逐渐增加,最后指向了最后一个元素地址,此时释放,也就是释放此时p之后的空间,这不行,会出现错误,free只能从起始位置开始释放,不能从某一点开始释放。

5、对同一块动态内存多次释放

    free(p);
    free(p);
    p = NULL;

每次释放完都赋值空指针,再者就是写上注释。

6、动态开辟内存忘记释放

要不内存泄露,内存一直被使用,直到被装满,电脑越来越卡。


二、练习

1、内存泄漏

void GetMemory(char* p)
{
    p = (char*)malloc(100);
}

void Test(void)
{
    char* str = NULL;
    GetMemory(str);
    strcpy(str, "hello world");
    printf(str);
}

int main()
{
    Test();
    return 0;
}

这里面有两个问题:

运行代码程序会出现崩溃的现象

程序存在内存泄漏的问题

str以值传递的形式给p

p是GetMemory函数的形参,只能函数内部有效,等此函数返回之后,动态开辟内存尚未释放并且无法找到,所以造成内存泄露

进入test函数后,str是传值方式,p相当于str的一个临时拷贝,传过去空指针后,动态开辟内存,把这块空间的首元素地址赋值给p指针,所以p也就指向了这个空间。但是这个函数没有返回值,导致开辟完后,str还是一个空指针,这时候进行拷贝相当于解引用空指针,所以程序崩溃。

要改正的话

void GetMemory(char** p)
{
    *p = (char*)malloc(100);
}

void Test(void)
{
    char* str = NULL;
    GetMemory(&str);
    strcpy(str, "hello world");
    printf(str);
    free(str);
    str = NULL;
}

或者

char* GetMemory(char* p)
{
    p = (char*)malloc(100);
    return p;
}

void Test(void)
{
    char* str = NULL;
    GetMemory(&str);
    strcpy(str, "hello world");
    printf(str);
    free(str);
    str = NULL;
}

下一篇继续写2。

结束。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值