new与malloc的区别和使用

发布时间:2023-05-22

一、new和malloc的基本概念

newmalloc都是用于动态分配内存的函数。dynamic memory allocation是指在程序运行时动态分配内存,也称堆分配(heap allocation),与静态内存分配(即编译时内存分配)相对应。C引入了newdelete来代替C语言中常用的mallocfreemalloc(memory allocation)函数定义在stdlib.h头文件中。malloc函数申请一块指定大小的内存块,并返回指向该内存块的指针。内存中的数据是未初始化的,需要使用memset函数来清零。 newdelete是C的关键字,是一对运算符。使用new运算符可以动态分配内存,并返回指向新内存的指针,而使用delete则可以将内存释放。

// malloc的用法示例
#include<stdlib.h>
int main(){
    int *p = (int*)malloc(sizeof(int));
    *p = 10;
    free(p);
    return 0;
}
// new的用法示例
#include <iostream>
int main(){
    int *p = new int;
    *p = 10;
    delete p;
    return 0;
}

二、new与malloc的区别

1.返回值类型不同

malloc返回void类型指针,在C++语言中需要进行强制类型转换才能赋值给指定类型的指针。new则返回指定类型的指针,不需要进行强制类型转换。

#include<iostream>
#include <stdlib.h>
int main(){
    int *p = (int*)malloc(sizeof(int));
    int *q = new int;
    std::cout << typeid(p).name() << std::endl;
    std::cout << typeid(q).name() << std::endl;
    free(p);
    delete q;
    return 0;
}
// 运行结果:Pv(void指针类型), Pi(int指针类型)

2.运算符重载

newdelete是C++的关键字,是一对运算符,支持重载。使用new可以自动调用构造函数,使用delete可以自动调用析构函数。

#include<iostream>
class A{
public:
    A(){std::cout << "A constructor" << std::endl;}
    ~A(){std::cout << "A destructor" << std::endl;}
};
int main(){
    A *a1 = (A*)malloc(sizeof(A));
    A *a2 = new A();
    free(a1);
    delete a2;
    return 0;
}
// 运行结果只有new能调用构造函数和析构函数

3.内存越界检查

new进行内存分配时,会进行越界检查。

#include<iostream>
#define LEN 10
int main(){
    int *p1 = (int*)malloc(sizeof(int) * LEN);
    int *p2 = new int[LEN];
    for(int i = 0; i < LEN+5; ++i){
        std::cout << p1[i] << " ";  // 越界访问p1,并不会抛出异常
    }
    std::cout << std::endl;
    for(int i = 0; i < LEN+5; ++i){
        std::cout << p1[i] << " ";  // 越界访问p2,会抛出异常
    }
    free(p1);
    delete[] p2;
    return 0;
}

4.分配对象空间不同

new可以同时分配对象和空间,而malloc只能分配空间。

#include<iostream>
#include <string.h>
class A{
public:
    int x;
    char* str;
};
int main(){
    A *a1 = (A*)malloc(sizeof(A));  // 只分配空间,需要手动初始化对象
    a1->x = 1;
    a1->str = (char*)malloc(sizeof(char) * 10);
    strcpy(a1->str, "hello");
    std::cout << "x = " << a1->x << ", str = " << a1->str << std::endl;
    free(a1->str);
    free(a1);
    A *a2 = new A();  // 分配空间并初始化对象
    a2->x = 2;
    a2->str = (char*)malloc(sizeof(char) * 10);
    strcpy(a2->str, "world");
    std::cout << "x = " << a2->x << ", str = " << a2->str << std::endl;
    free(a2->str);
    delete a2;
    return 0;
}

三、小结

newmalloc都是用于动态分配内存的函数。newdelete是C++的关键字,支持运算符重载和对析构函数的调用,可以自动调用构造函数和析构函数。new进行内存分配时会进行内存越界检查,malloc不会。new可以同时分配对象和空间,而malloc只能分配空间。选择使用哪个函数,需要结合具体的情况来考虑。