gpt4 book ai didi

C++对象内存消耗

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:22:24 26 4
gpt4 key购买 nike

首先:这个问题不是关于“如何使用delete运算符”,而是关于“为什么许多小尺寸的类对象会占用大量内存”。假设我们有这段代码:

class Foo
{

};

void FooTest()
{
int sizeOfFoo = sizeof(Foo);

for (int i = 0; i < 10000000; i++)
new Foo();
}

空类 Foo 的大小是 1 个字节,但是执行代码时它会消耗大约 600Mb 的内存。怎么样?

更新。我已经在 Visual Studio 2010 的 Win10 x64 上对此进行了测试。操作系统任务管理器的内存使用情况。

最佳答案

C++ 堆管理器有 4 种不同的“模式”,在这些模式下它会在对象周围保留或多或少的空间。这些是

  1. Release模式,正常运行
  2. Release模式,在调试器下运行
  3. Debug模式,正常运行
  4. Debug模式,在调试器下运行

额外的内存用于无人区(0xFDFDFDFD)、对齐到 16 字节边界(0xBAADF00D)、堆管理等。

我建议阅读 this post并查看调试器中的 4 个场景,打开原始内存 View 。你会学到很多东西。对于情况 1 和 3,插入一个暂停,您可以在其中将调试器附加到正在运行的进程,而在情况 2 和 4 中,您应该先运行调试器,然后从那里启动可执行文件。

我曾经在解释缓冲区溢出时演示 C++ 堆是如何工作的。这是您可以使用的演示程序,它并不完美,但可能有用:

#include "stdafx.h"
#include <Windows.h>
#include <iostream>
#include <stdio.h>
void SimpleBufferOverrunDemo( int argc, _TCHAR* argv[] ) ;

int _tmain(int argc, _TCHAR* argv[])
{
SimpleBufferOverrunDemo(argc, argv);

getchar();
return 0;
}

void SimpleBufferOverrunDemo( int argc, _TCHAR* argv[] )
{
if (argc != 2)
{
std::cout << "You have to provide an argument!\n";
return;
}

// Allocate 5 bytes
byte* overrunBuffer = new byte[5];

// Demo 1: How does the memory look after delete? Uncomment the following to demonstrate
//delete [] overrunBuffer; //0xfeeefeee in debug mode.
//DebugBreak();

// Demo 2: Comment Demo 1 again.
// Provide a 5 byte sequence as argument
// Attach with WinDbg and examine the overrunBuffer.

// 2.1. How many heaps do we have?
// !heap -s

// 2.2. How to find the heap block and how large is it?
// !heap -x [searchAddress]
// !heap -i [blockAddress] -> Wow 72 bytes block size for 5 allocated bytes!

// 2.3. Show that _HEAP_ENTRY does not work any more.

// Demo 3: Write behind the 5 allocated bytes.
// Provide more than 5 bytes as argument, depending on how what you want to destroy
// 3.1 Write into the no mans land.
// 3.2 Write into the guard bytes.
// 3.3 Write into the meta data section of the following heap block! -> When does it crash?

std::wstring arg = argv[1];

for (size_t i = 0; i < arg.size(); i++)
{
overrunBuffer[i] = (byte)arg[i];
}

// Crash happens not where it was caused(!) This is important!
std::cout << "Now we do a plenty of other work ...";
::Sleep(5000);

delete[] overrunBuffer;

// Demo 4: Demonstrate page heap / application verifier!
}

关于C++对象内存消耗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37038410/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com