如何判断 pointer/address 是否是动态分配的?

How can I tell whether a pointer/address is dynamically allocated?

我正在尝试减少内存泄漏。
显然最好的解决方案是首先不要泄漏内存。

但在我的例子中,我需要查看现有指针,并确定是否有任何指针是动态分配的并且需要删除。

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

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

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

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

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

你应该使用智能指针。

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

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

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

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

How can I tell whether a pointer/address is dynamically allocated?

一般情况下不能。

virtual address space of your process is likely to change. So ::operator new (or malloc) is often implemented to use system calls (on Linux, mmap(2) or sbrk(2))或重用以前free-d的内存(或::operator delete-d的一个)。

在 Linux 上,您可以解析 /proc/self/maps - 参见 proc(5)

学习也执行valgrind, and be aware of the address sanitizer instrumentation options of GCC.

在 C++ 中,您可以使用 smart pointers, and the garbage collection handbook explains many related issues (a major one being circular references,这对于多线程来说是一个复杂的问题。

C++也有placement new.

在 Linux 上,您可以 dlopen(3) many plugins, and that also adds complexity, but is quite useful (see Qt or RefPerSys as examples, and read the C++ dlopen minihowto).