繁体   English   中英

C ++ STL矢量模板如何在Visual Studio编译器实现中存储其对象?

[英]How does the C++ STL vector template store its objects in the Visual Studio compiler implementation?

我正在使用autoexp.dat和DLL扩展Visual Studio 2003调试器,以改进它在监视窗口中显示数据的方式。 我使用DLL而非仅使用基本的autoexp.dat功能的主要原因是我希望能够有条件地显示内容。 例如,我想说“如果名称成员不是空字符串,则显示名称,否则显示[其他成员]”

我对OOP还是很陌生,还没有使用STL的经验。 因此,可能是我缺少明显之处。

我在显示向量成员时遇到了麻烦,因为我不知道如何获取指向实际值存储在内存中的指针。

我认为值存储在连续的内存块中是正确的吗? 还有什么方法可以访问指向该内存的指针?

谢谢!

[编辑:]为了澄清我的问题(我希望):

在调试器调用的DLL中,我使用了一个称为ReadDebuggeeMemory的函数,该函数可复制对象使用的内存。 它不会复制对象指向的内存。 因此,我需要知道内部指针的实际地址值,才能同时对其调用ReadDebuggeeMemory。 目前,获取矢量内容的常用方法是返回垃圾,因为该内存尚未被复制。

[更新:]

即使当我正在查看正确的指针_Myfirst时,我也变得很垃圾,因为当我应该一直使用指向矢量的指针时,我正在创建矢量的额外副本。 因此,问题就变成了:如何通过指向向量的指针访问指向向量内存的指针? 那有意义吗?

标准向量中的元素被分配为一个连续的存储块。

您可以通过获取第一个元素的地址来获得指向内存的指针,这可以通过以下几种方法完成:

std::vector<int> vec;
/* populate vec, e.g.: vec.resize(100); */

int* arr = vec.data();   // Method 1, C++11 and beyond.
int* arr = &vec[0];      // Method 2, the common way pre-C++11.
int* arr = &vec.front(); // Method 3, alternative to method 2.

但是,除非您需要将基础数组传递给某些旧接口,否则通常可以直接在vector上使用运算符。

请注意,您最多只能访问返回值的vec.size()元素。 除此之外,访问都是不确定的行为(即使您认为有保留的能力)。

如果您有一个指向矢量的指针,则可以通过取消引用来完成上述操作:

std::vector<int>* vecptr;

int* arr = vecptr->data(); // Method 1, C++11 and beyond.
int* arr = &(*vecptr)[0];  // Method 2, the common way pre-C++11.
int* arr = &vec->front();  // Method 3, alternative to method 2.

更好的是,尝试获得参考。

关于您的解决方案

您想出了解决方案:

int* vMem = vec->_Myfirst;

唯一可行的方法是对特定编译器版本的特定实现。 这不是标准的,因此不能保证在编译器之间,甚至在不同版本的编译器之间都可以使用。

如果您仅在单个平台和编译器上进行开发,则似乎可以,但是最好根据选择的标准方法进行开发。

是的,这些值存储在内存的连续区域中,您可以使用第一个元素的地址来自己访问它。

但是,请注意,更改矢量大小的操作(例如push_back)会导致重新分配矢量,这意味着内存可能会移动,从而使指针无效。 如果使用迭代器,也会发生相同的情况。

vector<int> v;

v.push_back(1);

int* fred = &v[0];

for (int i=0; i<100; ++i)
  v.push_back(i);

assert(fred == &v[0]); // this assert test MAY fail

一旦我从拥有向量变量更改为拥有指向向量的指针,就无法实现GmanRoddy建议的解决方案,这很可能是因为我太笨了。

我找到了我一直在寻找的指针:_Myfirst

所以我的代码在我使用时有效

std::vector<int>* vec;

int *vMem = vec->_Myfirst;

我能够访问_Myfirst很惊讶。 我本来希望它是私人会员。 但显然不是...

您无法实施Gman和Roddy建议的解决方案,因为它们可以回答,看似正确,但与您的情况无关。

当开发用于与autoexp.dat一起使用的表达式评估(EE)的Addin Dll时,您将从过程中获得一个指向矢量对象的原始指针。 但是Dll在Visual Studio调试器的过程中运行,因此访问矢量数据的唯一方法是通过ReadDebuggeeMemory函数。

您应该使用该原始指针和ReadDebuggeeMemory()将Debugee进程中的某个对象占用的内存读取到本地缓冲区/对象。 (对于Debugger进程是本地的,表示您的dll)。 然后,如果它是指针,则从本地对象获取必要的数据,然后必须再次使用ReadDebuggeeMemory()来将其指向的对象读取到另一个本地位置。 等等。

对于矢量对象(我自己还没有做过具体介绍),您应该1.将矢量对象读取(ReadDebuggeeMemory())到本地对象。 2.获取向量的大小(我假设它是向量类中的非指针数据)。3.获取指向该连续内存位置的指针,并将该块读取(ReadDebuggeeMemory())到本地缓冲区/块。 块大小为sizeof(VectorType)* VectorSize(以字节为单位)。 (如果它不是连续的,那么事情将会更加复杂,但是思想是相同的)。 4.由于向量包含指针,因此必须将每个项目分别读取(ReadDebuggeeMemory())到本地存储器中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM