![](/img/trans.png)
[英]Does the C++ standard specify STL implementation details for the compiler?
[英]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
您无法实施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.