用VS2010查看类的内存布局,这里用两种方法

(1)MSVC有个隐藏的“/d1”开关,通过这个开关可以查看项目中类的内存布局情况。

修改项目属性,添加”/d1 reportSingleClassLayoutCC”开关,表示需要查看类CC的内存布局。

/d1 reportAllClassLayout 是查看所有类的布局,这样编译后会在输出界面上输出很多类的布局

/d1 reportSingleClassLayoutXX,"XX"是填入你想查看的类的名字,编译后会在输出界面上输出类的布局,任何匹配它的类名都会被输出。比如想看class A,你输入了/d1reportSingleClassLayoutA,但是你会发现会编译器输出很多无关的类,如struct ABC、Class inAttribute Class dbA...因为它们的类名都包含有A这个字母。

(2)通过添加自定义的外部工具,将类的内存布局在cmd界面上打印出来

1、首先新建一个bat文件,可以命名为classlayout.bat,保存在VC++的目录下,就是调用了下cl.exe而已

@echo off

call "%VS120COMNTOOLS%vsvars32.bat"

if "%2" == "" goto error
if "%1" == "" goto error
cl.exe /nologo /w /Zs /d1reportSingleClassLayout%2 %1
goto :eof :error
echo Error:参数错误 - 是否划定了类名?
goto :eof

2、然后新建一个cpp文件,会创建通道并创建子进程执行批处理。然后捕获批处理的标准输出,并过滤内容,只输出想要的。。。

#include <iostream>
#include <fstream>
#include <string>
#include <windows.h>
using namespace std; char g_name[101] = {}; bool CMDLine(char* cmd)
{
SECURITY_ATTRIBUTES sa;
HANDLE hRead,hWrite; sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
if (!CreatePipe(&hRead, &hWrite, &sa, 0))
{
cout << "CreatePipe失败" << endl;
return false;
}
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
ZeroMemory(&pi, sizeof(pi));
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
if (!CreateProcess(NULL,cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi))
{
cout << "CreateProcess失败" << endl;
return false;
}
CloseHandle(hWrite); char buffer[128] = { 0 };
DWORD bytesRead; bool bFindIt = false;
bool bFindEnd = false;
char *pBegin = NULL;
char *pError = NULL;
//// ofstream ofile("c:\\out2.txt", ios_base::binary); cout << "Waiting..." << endl;
//WaitForSingleObject(hRead,INFINITE);
while (ReadFile(hRead, (LPVOID)&buffer, 127, &bytesRead, NULL))
{
buffer[bytesRead] = '\0';
////// ofile << "Block:\n";
//// ofile << (char*)buffer;
//// continue; if(pError = strstr(buffer, "error C")) //输出错误
{
char *pReturn = strstr(pError, "\r");
if(pReturn)
{
*pReturn = '\n';
*(pReturn+1) = '\0';
}
cout << pError << (pReturn?"":"\n");
continue;
} if(!bFindIt && (pBegin = strstr(buffer, g_name)))
{
system("cls");
bFindIt = true; char *pEnd = strstr(pBegin, "\r\n\r\n\r\n"); //每个class间至少3个
if(pEnd)
{
*(pEnd+6) = '\0';
bFindEnd = true;
} cout << "class" << pBegin;
continue;
} if(bFindIt && !bFindEnd)
{
char *pEnd = strstr(buffer, "\r\n\r\n\r\n");
if(pEnd)
{
*(pEnd+6) = '\0';
bFindEnd = true;
} cout << (char*)buffer;
}
} //// ofile.close();
if(false == bFindIt)
cout << "\n未找到class" << g_name << endl << endl; return true;
} int main(int argc, char*argv[])
{
if(argc != 3)
goto end; cout << argv[1] << endl;
cout << argv[2] << endl; char *cppPath = argv[1];
while(*cppPath)
cppPath++;
if(cppPath - argv[1] < 5 || _strnicmp(cppPath-4, ".cpp", 4))
goto end;
if(*argv[2] == '\0')
goto end;
else
_snprintf(g_name, 100, " %s\t", argv[2]); char cmd[201] = {};
_snprintf(cmd, 200, "D:\\VS2010\\VC\\bin\\classlayout.bat \"%s\" \"%s\"", argv[1], argv[2]); cout<<cmd<<endl;
CMDLine(cmd);
system("pause");
return 0; end:
cout << "error: 输入参数不正确,是否已选中类名?" << endl;
system("pause");
return 0;
}

这里要添加两个system("pause");否则到时候会存在闪退的情况

  1. 里面的ofile用来将所有捕获到的内容输出到文件的,想打开它,取消里面的////注释即可!!!
  2. 里面的_snprintf(g_name, 100, " %s\t", argv[2]),是为了尽可能查找到类名,若改为"class %s\t",有时会找不到,因为ReadFile是按块读取的,两个块有可能从"class %s"中间断开。。。我们这样减小了这种可能,,当然,只是减小而已。
  3. 这也会过滤error warning等
  4. struct的内存布局输出前缀也是"class"
  5. 这里提醒,如果直接复制代码,需要注意代码中的那个路径要改成你电脑上的classlayout.bat文件的路径

3、编译通过后,配置成外部工具,工具->外部工具->添加,命令:找到你的可执行文件,参数如图所示,标题任意。

4、在使用前,确保你要查看的类所在的cpp文件编译通过,使用时,先选中你要查看的类的名字,再在工具中找到你起的名字(classlayout)就可以

注意:

(1)如果你的显示CreateProcess失败,你可以看下你的项目属性中字符集选用的是不是多字节字符集

(2)如果cmd格式不对,应该也是上述设置的问题

VS2010下如何查看类的内存布局的更多相关文章

  1. cl查看类的内存布局

    查看单个类的内存布局 Microsoft Visual Studio编译器cl的编译选项可以查看源文件中某个C++类的内存布局,对于想了解某个对象的内存布局的人来说十分直观和方便. • 命令格式    ...

  2. [CPP] 类的内存布局

    本文可以解决下面 3 个问题: 以不同方式继承之后,类的成员变量是如何分布的? 虚函数表及虚函数表指针,在可执行文件中的位置? 单一继承.多继承.虚拟继承之后,类的虚函数表的内容是如何变化的? 在这里 ...

  3. 继承虚函数浅谈 c++ 类,继承类,有虚函数的类,虚拟继承的类的内存布局,使用vs2010打印布局结果。

    本文笔者在青岛逛街的时候突然想到的...最近就有想写几篇关于继承虚函数的笔记,所以回家到之后就奋笔疾书的写出来发布了 应用sizeof函数求类巨细这个问题在很多面试,口试题中很轻易考,而涉及到类的时候 ...

  4. c++类的内存布局

    问题: 考察了reinterpret_cast和static_cast的区别.顺道发现了一个可以查看c++内存布局的工具(在VS中). 结果: 前两个输出的地址形同,后一个不同. class A{in ...

  5. 使用sos查看.NET对象内存布局

    前面我们图解了.NET里各种对象的内存布局,我们再来从调试器和clr源码的角度来看一下对象的内存布局.我写了一个测试程序来加深对.net对象内存布局的了解: using System; using S ...

  6. c++中如何查看一个类的内存布局

    打开VS command prompt,输入下述命令可以看到对象的内存布局. cl a.cpp -d1 reportSingleClassLayout[classname] //  reportSin ...

  7. C++类继承内存布局(一)

    转自:http://blog.csdn.net/jiangyi711/article/details/4890889# 一 类布局 不同的继承方式将导致不同的内存布局 1)C结构 C++基于C,所以C ...

  8. 【C++对象模型】使用gcc、clang和VC++显示C++类的内存布局

    引言 各种C++实现对C++类/对象的内存布局可能有所不同,包括数据成员的顺序.虚函数表(virtual table: vtbl)的结构.继承关系的处理等.了解C++类/对象的布局,对于理解C++各种 ...

  9. C++类继承内存布局(三)

    参考:http://blog.csdn.net/jiangyi711/article/details/4890889# (三)成员函数 类X中每一个非静态成员函数都会接受一个特殊的隐藏参数——this ...

随机推荐

  1. mybatis中传集合时 报异常 invalid comparison: java.util.Arrays$ArrayList and java.lang.String

    犯了一个低级的错误,在传集合类型的参数时,把他当成字符串处理了,导致报类型转换的错误 把  and nsrsbh!=' ' 删掉就行了

  2. LSTM+CRF进行序列标注

    为什么使用LSTM+CRF进行序列标注 直接使用LSTM进行序列标注时只考虑了输入序列的信息,即单词信息,没有考虑输出信息,即标签信息,这样无法对标签信息进行建模,所以在LSTM的基础上引入一个标签转 ...

  3. 集成多种协议、用于 USBC 端口的快充协议芯片IP2723

    1. 特性  快充规格  集成 QC4/QC4+输出快充协议 - 兼容 QC2.0/QC3.0 - 支持 Class B 电压等级  集成 FCP 输出快充协议  集成 SCP 输出快充协议  集成 ...

  4. apache状态显示报错AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdo...is message

    今天启动apache查看状态发现报错,说不能确认服务器完全确认域名,以下是报错内容: [root@localhost ~]# service httpd status Redirecting to / ...

  5. hessian-serialization

    http://hessian.caucho.com/doc/hessian-serialization.html Table of Contents 1.  Introduction2.  Desig ...

  6. Pusher Channels Protocol | Pusher docs https://pusher.com/docs/channels/library_auth_reference/pusher-websockets-protocol

    Pusher Channels Protocol | Pusher docs https://pusher.com/docs/channels/library_auth_reference/pushe ...

  7. (003)每日SQL学习:普通视图和物化视图

    关于这一点一直就是很懵懂的状态,今天特意网上查了一下资料,以下摘抄网上比较好的答案.以作记录. 普通视图和物化视图的区别答曰:普通视图和物化视图根本就不是一个东西,说区别都是硬拼到一起的,首先明白基本 ...

  8. WPF mvvm 验证,耗时两天的解决方案

    常用类 类名 介绍 ValidationRule 所有自定义验证规则的基类.提供了让用户定义验证规则的入口. ExceptionValidation 表示一个规则,该规则检查在绑定源属性更新过程中引发 ...

  9. 【Azure Developer】使用Microsoft Graph API创建用户时候遇见“401 : Unauthorized”“403 : Forbidden”

    问题描述 编写Java代码调用Mircrosoft Graph API创建用户时,分别遇见了"401 : Unauthorized"和"403 : Forbidden&q ...

  10. Oracle删除表中的重复数据

    Oracle数据库删除表中的重复数据,只保留其中的一条,以两个字段为例,提供两种方法 ①.直接delete重复的数据 delete from table_name t1 where (t1.col1, ...