malloc使用后读取写入权限冲突

这是申请的空间不够,可以使用new来申请空间,new 肯定够

Node *p;

p=(Node*)malloc(sizeof(Node));

《=》p=new Node;

        初学数组的时候,有一个问题经常困扰着我,就是:我们可不可以自己在程序里定义一个数组的大小而不是在函数开头先声明一个很大的数组,然后仅仅使用它的一小部分?

请看下面的程序:
我们需要一个大小为 N ( N < 1000)的数组,我们通常这么写:

int main(void) {

    int arr[1000] = { 0 };
    int N = 0;
    int i = 0;

    printf("请输入数组的大小\n");
    scanf("%d", &N);

    printf("请输入%d个数\n", N);
    for (i = 0; i < N; i++)
        scanf("%d", &arr[i]);

    return 0;
}

每次这么写我都觉得自己在绕远路,为什么就不能直接把输入的变量 N 当作数组的大小直接使用?
比如这样:arr[N],但是很遗憾,每次编译器都把你扼杀在程序编译之前!

C99才可以用变量做数组定义的大小
并且可以在程序中随时声明变量。(C99前我们需要在函数的最前面的区域对所有变量进行声明)

如果我不想用上面那种笨笨的办法,又没有支持C99的编译器,我该怎么办?

可以这么做:
int* arr = (int*)malloc(sizeof(int) * N)

sizeof(int) 代表数组中每个元素的类型
N 代表数组的元素个数

所以malloc的意义是向 堆区 要了一块sizeof(int) * N 这么大的空间

malloc 与 free ——好哥俩

malloc

头文件stdlib
原型void* malloc(size_t size)
所以需要根据实际你需要的类型对其强制类型转换
返回值
成功时,返回指向新分配内存的指针。为避免内存泄漏,必须用 free() 或 realloc() 解分配返回的指针。
失败时,返回空指针(NULL)
参数:size - 要分配的字节数

定义
分配 size 字节的未初始化内存。
若分配成功,则返回为任何拥有基础对齐的对象类型对齐的指针。

若 size 为零,则 malloc 的行为是实现定义的。例如可返回空指针。亦可返回非空指针;但不应当解引用这种指针,而且应将它传递给 free 以避免内存泄漏。

malloc - cppreference.com​zh.cppreference.com/w/c/memory/malloc

free

头文件stdlib
原型void free( void* ptr );
参数:指向要解分配的内存的指针
返回值:无
此函数接收空指针(并对其不处理)以减少特例的数量。不管分配成功与否,分配函数返回的指针都能传递给 free()

这是什么意思?意思就是malloc与free成对出现,不要忘记写free哦。

定义:
解分配之前由 malloc() 、 calloc() 、 aligned_alloc (C11 起) 或 realloc() 分配的空间。

若 ptr 为空指针,则函数不进行操作[1]

若 ptr 的值 不等于之前从 malloc() 、 calloc() 、 realloc() 或 aligned_alloc() (C11 起) 返回的值[2],则行为未定义。

若 ptr 所指代的内存区域已经被解分配[3],则行为未定义,即是说已经以ptr 为参数调用 free() 或 realloc() ,而且没有后继的 malloc() 、 calloc() 或 realloc() 调用以 ptr 为结果。

若在 free() 返回后通过指针 ptr 访问内存[4],则行为未定义(除非另一个分配函数恰好返回等于 ptr 的值)。

free():将申请来的空间的 首地址 还给“系统”,只要申请到了空间就一定要归还

毕竟有借有还,再借不难嘛
 

解读 free

注释1:释放空指针有何意义?

我们在声明一个指针时,一般把它初始化为0,也就是NULL。

这样做的好处是,如果我们在后面的程序中没有让这个指针指向一块具体的空间,这个指针不会是野指针,方便我们用来判断。比如 if(p != NULL)

我们还知道,当malloc失败时返回的是 NULL
所以我们一开始写上free是好习惯,因为我们不知道我们会不会用到我们声明的指针,也不知道malloc能不能成功
这时候,free空指针就是有意义的了

注释2:molloc申请到的指针 与 free要释放的指针保持一致

#include<stdio.h>

int main() {

    int* p;

    p = (int*)malloc(100 * 1024);

    p++;    //改变了 p 的首地址;

    free(p);//free 没有得到 malloc时 分配给p的首地址,程序崩溃
    return 0;
}

注释3:free释放空间后,被释放的指针成为野指针,不能直接使用它

#include<stdio.h>

int main() {

    int* p;

    p = (int*)malloc(100 * 1024);

    p++;

    free(p);
    p++;//free 释放后 p 成为了野指针,程序崩溃

    return 0;
}

注释4:不能多次释放同一次malloc申请的地址

#include<stdio.h>

int main() {

    int* p;

    p = (int*)malloc(100 * 1024);

    p++;

    free(p);
    free(p);

    return 0;
}

现在我们就可以改进我们上面的程序啦!

#include<stdlib.h>

int main(void) {

    int i = 0;
    int N = 0;
    int* arr;

    printf("请输入数组的大小\n");
    scanf("%d", &N);

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

    printf("请输入%d个数\n", N);
    for (i = 0; i < N; i++)
        scanf("%d", &arr[i]);

    free(arr);
    return 0;
}

什么?不是改进吗?怎么行数反而变多了?

测测你能给系统分配多大空间?

#include<stdlib.h>

int main(void) {

    void* p;
    int i = 0;

    //每次申请100M,失败返回空指针0,退出循环
    while ((p = malloc(1024 * 1024 * 100)))
        i++;

    printf("最多分配%d00M内存", i);

    return 0;

}

如果忘记了free?

我们一次程序中可以申请的内存是有限的。

如果你只是平时写简单的程序,写完就关闭,退出去了,这时忘记了free的话,不会对任何人造成影响,因为操作系统有清除曾使用的内存的机制

但是如果是一个持续运行的服务器呢?堆区中所有的空间都被你申请了呢?

free的常见问题

  • 申请了没有free -> 长时间运行内存逐渐下降
  • free 后再free
  • 地址变更后,直接去free

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

五敷有你

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

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

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

打赏作者

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

抵扣说明:

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

余额充值