C/C++ 内存分配管理

C/C++语言中内存分配方式

1、从静态存储区分配

内存在程序编译期间就已经分配好了,这块内存在程序的整个运行期间都存在,包括全局变量、static静态变量

2、在栈上分配

函数内部的局部变量按照一般方式是在在栈上创建,函数执行结束时局部变量生命周期结束,这些存储单元被自动回收。栈内存分配运算内置于处理器的指令集,效率高,但是占内存空间有限

3、在堆上动态分配

使用函数malloc或者关键字new申请内存,使用完内存之后需要程序员手动使用函数free或关键字delete释放,否则会发生内存泄漏(即内存被无效占用)。动态内存的生命周期由程序员自己决定,方便灵活,但是容易产生内存碎片和内存泄漏等问题

内存分配相关函数

alloca:从栈空间申请内存,无需手动释放

malloc:从堆空间申请一段未初始化的内存,一般用memset()初始化这段内存

calloc:从堆空间申请一段已初始化为0的内存

realloc:在原来申请的堆内存的基础上,调整内存的大小

free:用于释放申请的堆内存

函数声明

void* malloc(unsigned size);

void* calloc(size_t num,szie_t size);

void* realloc(void* ptr,unsigned newsize);

函数的使用

malloc函数

void* malloc(unsigned size);

说明:

malloc函数向系统申请一段连续可用但未初始化的空间,并返回这块空间的起始地址。申请失败则返回NULL。

过程

1.包含头文件stdlib.h

2.调用函数malloc时要记得需要强制类型转换一下。因为malloc的返回类型是void*。

3.判断是否为空指针,如果是空指针的话就表示空间申请不成功。因此使用strerror以及errno函数来打印错误提示信息。

4.用指针偏移的方式使用,需要根据强制转换后的类型及进行偏移

5.使用完后要释放空间,并将指针置为空指针。(防止出现野指针)
 

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>//strerror函数的头文件
#include<errno.h>//errno的头文件
int main() {
    //申请空间
    int* p = (int*)malloc(20);//申请的空间的单位是字节,这里表示申请20个字节。并强制转为int*类型


    //判断是否申请成功
    if (p == NULL) {
        printf("%s\n", strerror(errno));
        return;
    }
    //使用
    int i = 0;
    for (i = 0;i < 5;i++) {
        *(p+i) = i;
    }
    for (i = 0;i < 5;i++) {
        printf("%d ", *(p + i));
    }
    //释放
    free(p);
    p = NULL;
    return 0;
}

calloc函数

void* calloc(size_t num,szie_t size);

说明:

calloc向内存空间申请num个大小为size的初始化为0(如果你是为指针类型的元素分配内存,那么这些元素通常会被初始化为空指针)的连续内存空间。申请成功就返回申请到的空间的地址。申请失败则返回NULL。

过程

1.包含头文件stdlib.h

2.调用函数calloc时要记得需要强制类型转换一下。因为calloc函数的返回类型是void*。

3.判断是否为空指针,如果是空指针的话就表示空间申请不成功。因此使用strerror以及errno函数来打印错误提示信息。

4.用指针偏移的方式使用,需要根据强制转换后的类型及进行偏移

5.使用完后要释放空间,并将指针置为空指针。(防止出现野指针)

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main() {
    //申请空间
    int* p = (int*)calloc(20,sizeof(int));//20表示申请空间的个数,
                                         //sizeof(int)获得int类型所占字节大小
    //判断是否申请成功
    if (p == NULL) {
        printf("%s\n", strerror(errno));//打印错误信息
        return;//结束
    }
    //使用
    int i = 0;
    for (i = 0;i < 5;i++) {
        *(p + i) = i;
    }
    for (i = 0;i < 5;i++) {
        printf("%d ", *(p + i));
    }
    //释放
    free(p);
    p = NULL;
    return 0;
}

realloc函数

void* realloc(void* ptr,unsigned newsize);

说明:

当malloc函数或者calloc函数申请的空间大小不满足当下要求时,使用realloc调整空间大小。ptr是原来的空间地址,newsize是新申请的空间大小,如果原内存空间后面有足够的空间,则直接扩容,否则需要寻找新的足够大的内存空间,返回申请到的空间的地址。申请失败则返回NULL,原内存不会被释放。

过程

1.包含头文件stdlib.h

2.调用函数realloc时要记得需要强制类型转换一下。因为calloc函数的返回类型是void*。

3.判断是否为空指针,如果是空指针的话就表示空间申请不成功。因此使用strerror以及errno函数来打印错误提示信息。

4.用指针偏移的方式使用,需要根据强制转换后的类型及进行偏移

5.使用完后要释放空间,并将指针置为空指针。(防止出现野指针)

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main() {
    //申请空间
    int* p = (int*)calloc(20, sizeof(int));//20表示申请空间的个数,
                                         //sizeof(int)获得int类型所占字节大小
    //判断是否申请成功
    if (p == NULL) {
        printf("%s\n", strerror(errno));//打印错误信息
        return;//结束
    }
    //使用
    int i = 0;
    for (i = 0;i < 5;i++) {
        *(p + i) = i;
    }
    int* ptr = (int*)realloc(p, 40);//将p指向的20个字节的空间改为40个字节的空间
    if (ptr != NULL) {//是否申请成功
        p = ptr;
        for (i = 5;i < 10;i++) {
            *(p + i) = i;
        }
        for (i = 0;i < 10;i++) {
            printf("%d ", p[i]);
        }
    }
    else {
        printf("realloc:%s\n", strerror(errno));
    }
    //释放
    free(p);
    p = NULL;
    return 0;
}

new操作符

new 类型(参数)

说明:

new是C++中用于动态内存分配的操作符。在程序运行时创建一个新的对象,并返回该对象指针与malloc和calloc相比,new具有更好的类型安全性,并能自动调用构造函数进行对象的初始化,所以不需要进行类型转换。同时,new操作符会根据请求的类型自动计算所需的内存大小。在C++中,new操作符可以分配两种类型的内存:堆内存和自由存储区。堆内存是在程序运行时动态分配的内存,通常用于存储较大的数据结构,如数组和对象。自由存储区是程序运行时维护的一段内存区域,用来存储较小的数据结构,如指针和变量

代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<errno.h>
int main() {
    //申请空间
    int* p = new int(1);  //初始化为1

    //ClassA * pA = new ClassA();  //给自定义类分配空间,创建对象
    //使用
    (*p) = 2;
    p = NULL;
    return 0;
}

new和malloc的区别

语法:new是C++的运算符,而malloc是C标准库函数。所以只有new可以调用类的构造函数,而malloc不行

返回类型:new返回指向指定类型的已分配内存空间的指针,并且可以自动确定所需内存的大小,而malloc返回void*类型的已分配内存空间的指针,需要手动确定内存大小

异常处理:如果new分配内存空间失败,将抛出std::bac_alloc异常,而malloc只会返回一个空指针

用法:new适合分配具体的自定义类对象,malloc通常用于分配动态数组

内存对齐:new所分配的内存空间是按照所需类型的对齐方式自动对齐,而malloc需要手动调用特定函数才能达到对齐

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

qq_54881777

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

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

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

打赏作者

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

抵扣说明:

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

余额充值