首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >字节一面,new出来的对象真的不可以用free释放吗?

字节一面,new出来的对象真的不可以用free释放吗?

作者头像
程序员的园
发布2025-02-18 21:16:16
发布2025-02-18 21:16:16
32100
代码可运行
举报
运行总次数:0
代码可运行

本文是一道C++面试的基础题——new出来的对象可以用free释放吗?它甚至还有一个变体——malloc分配的内存可以使用delete释放吗?其实这两道题都是在考察new/delete、malloc/free的区别,只是面试官换了个问法而已。如果面试官直接问:new和malloc的区别是什么?可能会更熟悉一些。

理论分析

在进入正文前,在回顾下new/delete和malloc/free的区别:

  • new/delete是C++的运算符,malloc/free是C的库函数。
  • new/delete会调用对象的构造函数/析构函数,malloc/free不会。
  • new/delete返回的是指向对象的指针,malloc/free返回的是void指针。
  • new会自动计算需要分配的内存大小,malloc需要手动计算。

综上,new/delete在分配和释放内存的基础上会调用对象的构造函数和析构函数,而malloc/free只会分配和释放内存,不会调用构造函数和析构函数。如上可以作为该问题的回答。但是这并不是我想写这篇文章的目的。

结合如上理论知识,new出来的对象使用free释放时无法调用其析构函数;同理,malloc出来的内存使用delete释放时会调用其析构函数。这些原则要求我们必须配套使用new/delete和malloc/free。由此我猜想:

  • 针对POD类型,由于其不具备构造函数和析构函数,所以new/delete和malloc/free似乎就没有区别呀,两者貌似是可以混用的
  • 针对于非POD类型,由于其具备构造函数和析构函数,且其构造函数和析构函数可能存在内存、资源的分配与释放,所以new/delete和malloc/free在处理非POD类型时存在差异。必须要配套使用,不可混用

由上的理论分析可知,非POD类型必须配套使用new/delete和malloc/free已经达成共识了,只是对于POD类型,目前还持怀疑态度,所以本文将以实验的形式对POD类型进行验证。

代码实验

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <iosfwd>
#include <string>
#include <type_traits>

struct Point
{
int x;
int y;

friendstd::ostream& operator<<(std::ostream& os, const Point& p)
 {
  os << "(" << std::to_string(p.x) << ", " << std::to_string(p.y) << ")";
return os;
 }
};

template <typename T>
void using_pod_new_free()
{
for (size_t i = 0; i < 100000; i++)
 {
auto p = new T(10);
std::cout << *p << std::endl;
free(p);
 }
}

template <>
void using_pod_new_free<Point>()
{
for (size_t i = 0; i < 100000; i++)
 {
auto p = new Point(10,5);
std::cout << *p << std::endl;
free(p);
 }
}

template <typename T>
void using_pod_malloc_delete()
{
for (size_t i = 0; i < 100000; i++)
 {
auto p = (T*)malloc(sizeof(T));
if (p)
  {

   *p = 10;
   std::cout << *p << std::endl;
   delete p;
  }
 }
}

template <>
void using_pod_malloc_delete<Point>()
{
for (size_t i = 0; i < 100000; i++)
 {
auto p = (Point*)malloc(sizeof(Point));
if (p)
  {

   p->x = 10;
   p->y = 20;
   std::cout << *p << std::endl;
   delete p;
  }
 }
}


int main()
{
/*using_pod_new_free<int>();
 using_pod_malloc_delete<int>();*/

/*using_pod_new_free<float>();
 using_pod_malloc_delete<float>();*/

/*using_pod_new_free<long>();
 using_pod_malloc_delete<long>();*/

 using_pod_new_free<Point>();
 using_pod_malloc_delete<Point>();

return0;
}

运行如上代码在windows平台下,IDE为MSVC2022,C++20标准,编译程序,运行程序,并借助VS自带的性能分析工具,分析内存使用率,并未出现内存泄漏。

尽管如上测试具有不充分性,但结合理论分析和实验,确认所有的POD类型都可以混用。

总结

结合面试问题,并分析new/delete和malloc/free的区别,在分析其原理的基础上,通过实验验证POD类型混用new/delete和malloc/free是可行的,而非POD类型必须配套使用。但是,为了代码的可维护性,建议还是使用new/delete和malloc/free配套使用。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-02-14,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 理论分析
  • 代码实验
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档