如果有的话,可以在C ++中互换使用delete
和free
吗?
我的担忧如下:假设使用malloc
/ free
时混音不正确
new
/ delete
(更不用说new[]
/ delete[]
)。但delete
和free
做同样的事情;
幸运的是,这在测试中没有受到影响。之后这可能导致生产崩溃。
如何执行某种检查以防止这种情况发生?如果这两个人混在一起,我可以得到警告吗? 如果不是在编译时,可能在运行时有一些代码检测?我该怎么做 此?
这个问题的目的是找到避免无意中混淆使用的方法。
答案 0 :(得分:11)
不让它们混淆的简单方法是永远不要使用malloc(),那么你永远不会想要调用free()。为避免此问题而创建的基础结构称为“代码审查”,但在这种情况下,快速“grep malloc(”或“grep free(”在代码库上可能就足够了。
答案 1 :(得分:7)
从不。如果它的工作原理是纯粹的实施意外。不要依赖这种行为。
答案 2 :(得分:5)
要回答第二个问题,如果您同时控制malloc
/ free
和operator new
/ delete
,则可以存储额外信息以与两者返回的指针相关联告诉你他们是如何分配的。将指针传递给free
或operator delete
时,请检查它是否由相应的函数分配。如果没有,则断言或提出异常或做任何事情来报告不匹配。
通常这是通过分配额外的内存来完成的,例如,给定malloc(size)
或operator new(size)
,您分配size + additional space
并在那里推送额外的信息。
答案 3 :(得分:5)
你可以确保永远不会让他们混淆的唯一方法是:
手动调用delete 或 free只是一个bug的邀请。
答案 4 :(得分:4)
您应该始终在C ++中使用new
和delete
,因为只有new
和delete
会调用对象的构造函数和析构函数。< / p>
如果您发现必须同时使用它们(例如,如果您正在与C库连接),那么彻底的代码审查应仔细审查free()
的任何用途,以确定是否不是它们对应于malloc()
,以及它们是否在C语境中使用。
答案 5 :(得分:1)
如果我必须编纂它,我会在样式指南中添加如下内容:
free()
只能在对象的私有指针字段上调用。 malloc()
ed缓冲区(或从C API返回的缓冲区,调用者必须free()
)分配给对象的私有指针字段。free()
的私有指针字段 - 只能用于此目的的缓冲区。free()
,在对象的生命周期内替换free()
- 能够使用缓冲区时会出现异常。在这种情况下,您可以在替换期间最近从私有字段复制的值上调用free()
,而不是直接在字段值上调用。换句话说,在任何使用malloc / free的东西周围粘贴一个包装器。这个包装器可以是每个人使用的单个模板,也可以允许将deletor函数设置为free()
的智能指针。然后在代码审查中,如果你在其他任何地方看到对malloc / free的调用,那就错了。
基本上,阻止这是一个问题的最好方法是在一般的资源处理之上。在C语言中,人们在流而不是free()
上意外调用fclose()
时没有遇到重大问题。
答案 6 :(得分:0)
在释放使用new分配的内容时,应始终使用delete或delete []。对于malloc和free来说也是如此。
如果使用free来删除new:ed类,则不会正确调用析构函数。 new和delete也不一定使用malloc / free进行分配,所以你最终也可能破坏你的堆。
答案 7 :(得分:0)
delete
分配的内容,始终使用new
,delete []
分配使用new []
和free()
分配的内容。
new和new []从不同的堆分配而不是malloc()并使用错误的free()/ delete将尝试从错误的堆中释放。
答案 8 :(得分:0)
切勿将new/delete
与new[]/delete[]
或malloc()/free()
混合。在此基础上,至少在C ++中使用malloc()/free()
是值得怀疑的。
确保永远不会意外执行此操作的最简单方法是不要手动管理内存。在C ++中,有字符串和其他容器以及用于处理内存管理的智能指针。根本不需要手动执行此操作。 (我不确定上次我记得我输入delete
是否真的是我最后一次输入它。但如果我的记忆没有让我失望,那一定是2001年或2002年。)
答案 9 :(得分:0)
您可以编写自己的函数版本,在new / new [] / malloc中分配一些额外的内存来跟踪哪一个进行了分配。然后检查删除/删除[] / free是否使用了正确的功能来重新声明内存。您还可以通过这种方式检查混合new []和delete(不带[])之类的内容。您可能只想在调试版本中使用这些版本。
答案 10 :(得分:0)
您可以尝试在应用程序上运行valgrind以查看它是否捕获任何内容。 manual specifically mentions它能够捕获对内存块使用错误的释放函数的能力。但是,我认为在编译时没有办法做到这一点。
答案 11 :(得分:0)
避免错误使用malloc / free或new / delete的一种方法是不要直接调用这些函数,通过包装层调用它们。在包装层中,您可以管理由您自己分配的指针,并保证错误将明确地得到错误。
答案 12 :(得分:-1)
为什么不计算malloc语句的总数并计算总数为free?对New和删除做同样的事情。可以使用正则表达式自动执行该过程。
答案 13 :(得分:-2)
我做过的一件事就是重新实现malloc和free 在C ++中,所以它在引擎盖下调用new / delete。不是 最佳,但它在较小的项目上足够好。