C++17 的 'new' 运算符还能泄漏内存吗?
C++17 can the 'new' operator still leak memory?
我正在做一个项目,需要一个字符缓冲区来通过网络发送结构。我正在使用:
char* buf = new char[sizeof(obj)];
后来有人告诉我,如果我不删除就那样做会泄漏内存。我用 Visual Studio 2017 Professional 调试了我的程序,无论我做了多少次缓冲区,我的记忆都保持不变。
我的问题是:C++17 是否修复了 'new' 运算符可能导致的内存泄漏问题,或者这是我正在使用的编译器特有的问题?提前致谢!
在没有delete[]
的情况下调用new[]
确实会泄漏内存。除非你泄漏了大量缓冲区,否则你可能看不到它,这取决于你的应用程序的 RTL allocates/caches 内存在引擎盖下的方式。
传统上,使用 std::vector<char>
,甚至 std::string
是动态缓冲区的首选,让它们为您处理自己的内存,例如:
std::vector<char> buf(sizeof(obj));
or
std::string buf(sizeof(obj), 0);
如果您出于某种原因绝对需要 new[]
/delete[]
,请考虑使用 std::unique_ptr<char[]>
,让它为您调用 delete[]
,例如:
std::unique_ptr<char[]> buf(new char[sizeof(obj)]);
or
auto buf = std::make_unique<char[]>(sizeof(obj));
是的,这看起来像是内存泄漏。
如果不想在动态分配的内存上显式调用delete
,标准的解决方案是使用智能指针,通常使用“引用计数”来de-allocate安全记忆。
有关智能指针的更多信息:What is a smart pointer and when should I use one?
至于为什么你没有分配更多的内存——你在测量什么?通常会发生两种“分配”:
- 您的内存分配器从操作系统请求内存。
- 你的内存分配器 returns 指向那部分内存的指针。
(严格来说,这不是特定于您的 编译器 ,这是基于 new
的实现。如果您使用的是标准 Visual C++ 工具链,那么从这个意义上说,是的,new
的实现依赖于 Visual C++。这里是一个起点:https://docs.microsoft.com/en-us/cpp/standard-library/memory?view=vs-2019)
您可能正在测量 #1 -- 操作系统分配了多少内存。例如,sizeof(obj)
可能是 1 KB,而您的分配器可能已从操作系统请求 256K。因此,您 space 可以执行 new
并在该内存缓冲区中接收分配,而无需更改进程的 OS-level 内存占用。
作为实验,我建议连续分配更大的内存块:
const int alloc_size = 4; // then 5, 6, 7...
for (int i = 0; i < (2<<alloc_size); i++) {
// do your allocation here
}
然后找出在测量值发生变化之前您可以执行多少次分配。
我正在做一个项目,需要一个字符缓冲区来通过网络发送结构。我正在使用:
char* buf = new char[sizeof(obj)];
后来有人告诉我,如果我不删除就那样做会泄漏内存。我用 Visual Studio 2017 Professional 调试了我的程序,无论我做了多少次缓冲区,我的记忆都保持不变。
我的问题是:C++17 是否修复了 'new' 运算符可能导致的内存泄漏问题,或者这是我正在使用的编译器特有的问题?提前致谢!
在没有delete[]
的情况下调用new[]
确实会泄漏内存。除非你泄漏了大量缓冲区,否则你可能看不到它,这取决于你的应用程序的 RTL allocates/caches 内存在引擎盖下的方式。
传统上,使用 std::vector<char>
,甚至 std::string
是动态缓冲区的首选,让它们为您处理自己的内存,例如:
std::vector<char> buf(sizeof(obj));
or
std::string buf(sizeof(obj), 0);
如果您出于某种原因绝对需要 new[]
/delete[]
,请考虑使用 std::unique_ptr<char[]>
,让它为您调用 delete[]
,例如:
std::unique_ptr<char[]> buf(new char[sizeof(obj)]);
or
auto buf = std::make_unique<char[]>(sizeof(obj));
是的,这看起来像是内存泄漏。
如果不想在动态分配的内存上显式调用delete
,标准的解决方案是使用智能指针,通常使用“引用计数”来de-allocate安全记忆。
有关智能指针的更多信息:What is a smart pointer and when should I use one?
至于为什么你没有分配更多的内存——你在测量什么?通常会发生两种“分配”:
- 您的内存分配器从操作系统请求内存。
- 你的内存分配器 returns 指向那部分内存的指针。
(严格来说,这不是特定于您的 编译器 ,这是基于 new
的实现。如果您使用的是标准 Visual C++ 工具链,那么从这个意义上说,是的,new
的实现依赖于 Visual C++。这里是一个起点:https://docs.microsoft.com/en-us/cpp/standard-library/memory?view=vs-2019)
您可能正在测量 #1 -- 操作系统分配了多少内存。例如,sizeof(obj)
可能是 1 KB,而您的分配器可能已从操作系统请求 256K。因此,您 space 可以执行 new
并在该内存缓冲区中接收分配,而无需更改进程的 OS-level 内存占用。
作为实验,我建议连续分配更大的内存块:
const int alloc_size = 4; // then 5, 6, 7...
for (int i = 0; i < (2<<alloc_size); i++) {
// do your allocation here
}
然后找出在测量值发生变化之前您可以执行多少次分配。