如何判断指针/地址是否是动态分配的?

问题描述

我正在努力减少内存泄漏。
显然,最好的解决方案是首先不泄漏内存。

但在我的情况下,我需要查看现有的指针,并确定它们中的任何一个是否被动态分配并需要删除

给定一个特定的地址/指针,C++ 是否提供了一种方法来确定给定的地址是否指向堆?

奖励:
C++ 是否提供了一种方法来确定是否需要使用 delete[] 与普通的 delete 删除给定的堆地址?

解决方法

在 C++(和 C)中,指针指向任何地址。要知道您指向的内存类型,您需要查看进程内存映射。这将是特定于平台的。

在 Linux 上,/proc/<pid>/maps 文件包含此信息。

然而,即使指针指向堆,如果它是新指针的增量(想想数组),或者如果它是使用 malloc 而不是 {{1 }}。

,

你应该使用智能指针。

您无法知道指针指向何处,但使用智能指针意味着您可以避免删除任何指针。

在代码中的某个位置创建智能指针,只要您需要使用它指向的对象,该位置就会一直存在。然后,不要在代码周围传递智能指针(除非您需要转让/共享所有权),只需将引用传递给它指向的对象(或原始指针)。

当您的所有对象都以这种方式由智能指针管理时,您永远不必删除代码中的任何指针,因为您知道有一个智能指针将在正确的时间处理删除的指针。

void func(Object const& o) { /* ... */ }
void other_func(Object const* pp) { /* ... */ }

// ... somewhere else in the codebase

auto object_ptr = std::make_unique<Object>();

func(*object_ptr); // call function with a reference

other_func(object_ptr.get()); // call function with a raw pointer

奖励:

没有

知道自己创建了什么是您的责任,但同样,智能指针会为您处理:

auto array_ptr = std::make_unique<Object[]>(25); // allocate an array
,

如何判断一个指针/地址是否是动态分配的?

一般来说你不能。

您的流程的 virtual address space 可能会发生变化。所以function step3() { //finds both answers answer1 = top1 / (2*a); answer2 = top2 / (2*a); console.log(answer1 + " " + answer2); solutions = isNaN(answer1) console.log(solutions) if (solutions) { console.log("no real sol"); } step4() }(或malloc)通常被实现为使用系统调用(在Linux上,mmap(2)sbrk(2))或重用以前的::operator new-d内存(或 free-d 一个)。

在 Linux 上,您可以解析 ::operator delete - 请参阅 proc(5)

还要研究 valgrind 的实现,并注意 address sanitizer 检测 options of GCC

在 C++ 中,您可以使用 smart pointers,而 garbage collection handbook 解释了许多相关问题(主要问题是 circular references,多线程会成为一个复杂的问题)。>

C++ 也有 placement new

在 Linux 上,您可以dlopen(3) 许多插件,这也增加了复杂性,但非常有用(请参阅 QtRefPerSys 作为示例,并阅读 C++ dlopen minihowto ).