如何判断 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).
我正在尝试减少内存泄漏。
显然最好的解决方案是首先不要泄漏内存。
但在我的例子中,我需要查看现有指针,并确定是否有任何指针是动态分配的并且需要删除。
给定一个特定的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).